diff --git a/DEPS b/DEPS index 3822571..1ed31a1 100644 --- a/DEPS +++ b/DEPS
@@ -318,11 +318,11 @@ # 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': '6680ecf35131e9ef75948de60ddf0b539ba6a377', + 'v8_revision': 'ad0956c177c9a6990e78dc061c9b8d83a6320b1a', # 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': 'aaeeea0c42a877535428b146c7fd342ec19f0529', + 'angle_revision': '27836f2181738a69543f657898f4cd6994c4c4d7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -365,7 +365,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': 'a3f44aadbc5797b3e7a5a9f38473985eaf23d4cb', + 'freetype_revision': '97251fd5aa2a90041cf4f397a5e887b8d60ab0c2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -385,15 +385,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '0ad1d60e958e2f42e5fe9303035cc10eec1304f7', + 'catapult_revision': '19ad1237e35315125d897f6f438b3cd2798fc133', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. - 'chromium_variations_revision': 'ada6b2f7876642ae86fb79d8f98a636bfeddb36d', + 'chromium_variations_revision': '813d025bdac7bc5c3d966500a1c51c16f937f8b8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. - 'crossbench_revision': 'fda8bf910a70437f3334f02006a462d23920bef2', + 'crossbench_revision': '06981428c28d66678ebec13ca1fac3785cf51bb1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -405,7 +405,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '5b20d84d3a15033f9d698247f8159cf1a690fb2e', + 'devtools_frontend_revision': 'fc8a5ad2e2444574f74c2d89e30b9e737c95db62', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -445,7 +445,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '088b039f50f929adc83ea20c378bcc456f88a77e', + 'dawn_revision': '1244719685f0df31ffecea8cad822540cc9d96bf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -465,7 +465,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libavif # and whatever else without interference from each other. - 'libavif_revision': 'b33d9ebfc9612e86a20a9aa67afc90040ec98369', + 'libavif_revision': '676aded3501ff453c88a6d9ed1e5b4f33b458f3e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libavif # and whatever else without interference from each other. @@ -473,7 +473,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. - 'nearby_revision': '945ab524852422d6632f139a939bbc1019c3ec7f', + 'nearby_revision': 'ea7aa00e0cd99a0fab900ae55e727fd5acf672fd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling securemessage # and whatever else without interference from each other. @@ -806,7 +806,7 @@ }, 'src/chrome/test/data/autofill/captured_sites/artifacts': { - 'url': Var('chrome_git') + '/chrome/test/captured_sites/autofill.git' + '@' + 'fbd172ab07184d7abf6f9e9b08f7af7be804d9e3', + 'url': Var('chrome_git') + '/chrome/test/captured_sites/autofill.git' + '@' + '654ecc6e5f3948e6c2dd42df13d2345f4f88bac3', 'condition': 'checkout_chromium_autofill_test_dependencies', }, @@ -837,7 +837,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '8542a79e0febd8bcabca11f1aec6c1ebaced4798', + 'ce4f375bbbfa4e53c4a7aee65f0025ca475a2064', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1241,7 +1241,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ae18701204a7453817a5a26ebecd89883facdfda', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c4b0ff08d3975d0d7a8170c2014504d81d778288', 'condition': 'checkout_chromeos', }, @@ -1276,13 +1276,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '9c4fbc5a2a69e8388b9b5ce937aeb3c67ce7ca42', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2c3875ea1c41b98c8e5467bb7a56d27c97f30ae8', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '540a8838edc7d6075f35692e64bd1381b8a515a3', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '7c32916a74a355986e732ab6daba4435b337242a', 'condition': 'checkout_src_internal', }, @@ -1540,7 +1540,7 @@ Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'e8712e415627f22d0b00ebee8db99547077f39bd', 'src/third_party/libaom/source/libaom': - Var('aomedia_git') + '/aom.git' + '@' + '584717120f2997bc29b1e9becce3322be01fc807', + Var('aomedia_git') + '/aom.git' + '@' + '00ef4ff15e3e62c50e381eb00c08d7f709226d40', 'src/third_party/libavif/src': Var('chromium_git') + '/external/github.com/AOMediaCodec/libavif.git' + '@' + Var('libavif_revision'), @@ -1607,7 +1607,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '335728c987b3164ff25c58c06d29eb49e19e21d4', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '24c0dcc8513b8c1ba4ffbf934a399f89de646ffe', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4fbea0c9751ae8aa86629b197a28d8276a2b0da', @@ -1740,7 +1740,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '6dd190cea4a34d1f51794f42d94fd9b7df3477cf', + Var('chromium_git') + '/openscreen' + '@' + 'ba66153da90641c95731613db6582a5b64e6d847', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '58a00cf85c39ad5ec4dc43a769624e420c06179a', @@ -1933,10 +1933,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '3e71f3b643f8095babbd46cf4e7d34e4f1ddf7a8', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3acbf58bd5c2d28fb84d953e65de7582fad28faa', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '4fc748388076ebf618edb742505be93892e4057a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '179cec2be05f2b389c4afdf190319f623a4f2cb4', + Var('webrtc_git') + '/src.git' + '@' + '8284f2b4e8670529d039a8b6c73ec5f1d760bd21', # 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. @@ -2070,7 +2070,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': '5vT4Jv2tZoZUMaullP086elr9MQPZaPHsBuMLrt798UC', + 'version': 'eCk59QLGrOGxZpwAC5CLdvbgcNCZ5xMUXtlVZqhGT3IC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/aw_pdf_exporter.cc b/android_webview/browser/aw_pdf_exporter.cc index 348f960..92cb12f5 100644 --- a/android_webview/browser/aw_pdf_exporter.cc +++ b/android_webview/browser/aw_pdf_exporter.cc
@@ -96,6 +96,14 @@ const printing::PageRanges& page_ranges) { auto settings = std::make_unique<printing::PrintSettings>(); int dpi = Java_AwPdfExporter_getDpi(env, obj); + printing::PageMargins margins; + margins.left = MilsToDots(Java_AwPdfExporter_getLeftMargin(env, obj), dpi); + margins.right = MilsToDots(Java_AwPdfExporter_getRightMargin(env, obj), dpi); + margins.top = MilsToDots(Java_AwPdfExporter_getTopMargin(env, obj), dpi); + margins.bottom = + MilsToDots(Java_AwPdfExporter_getBottomMargin(env, obj), dpi); + settings->SetCustomMargins(margins); + int width = Java_AwPdfExporter_getPageWidth(env, obj); int height = Java_AwPdfExporter_getPageHeight(env, obj); gfx::Size physical_size_device_units; @@ -116,13 +124,6 @@ settings->SetPrinterPrintableArea(physical_size_device_units, printable_area_device_units, true); - printing::PageMargins margins; - margins.left = MilsToDots(Java_AwPdfExporter_getLeftMargin(env, obj), dpi); - margins.right = MilsToDots(Java_AwPdfExporter_getRightMargin(env, obj), dpi); - margins.top = MilsToDots(Java_AwPdfExporter_getTopMargin(env, obj), dpi); - margins.bottom = - MilsToDots(Java_AwPdfExporter_getBottomMargin(env, obj), dpi); - settings->SetCustomMargins(margins); settings->set_should_print_backgrounds(true); return settings; }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 3f9b6ec..f38b6a2 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -79,6 +79,8 @@ "accessibility/accessibility_delegate.h", "accessibility/accessibility_event_handler_manager.cc", "accessibility/accessibility_event_handler_manager.h", + "accessibility/accessibility_notification_controller.cc", + "accessibility/accessibility_notification_controller.h", "accessibility/accessibility_observer.h", "accessibility/autoclick/autoclick_controller.cc", "accessibility/autoclick/autoclick_controller.h",
diff --git a/ash/accelerators/accelerator_controller_impl.cc b/ash/accelerators/accelerator_controller_impl.cc index 4e6f4466..b908b2a 100644 --- a/ash/accelerators/accelerator_controller_impl.cc +++ b/ash/accelerators/accelerator_controller_impl.cc
@@ -191,17 +191,6 @@ base::RecordAction(UserMetricsAction("Accel_NewTab_T")); } -// Check if accelerator should trigger ToggleAssistant action. -bool ShouldToggleAssistant(const ui::Accelerator& accelerator) { - // Search+A shortcut is disabled on device with an assistant key. - // Currently only Google branded device has the key. Some external keyboard - // may report it has the key but actually not. This would cause keyboard - // shortcut stops working. So we only check the key on these branded - // devices. - return !(accelerator.IsCmdDown() && accelerator.key_code() == ui::VKEY_A && - IsGoogleBrandedDevice() && ui::DeviceKeyboardHasAssistantKey()); -} - void HandleSwitchToLastUsedIme(const ui::Accelerator& accelerator) { base::RecordAction(UserMetricsAction("Accel_Previous_Ime")); if (accelerator.key_state() == ui::Accelerator::KeyState::PRESSED) { @@ -1241,11 +1230,8 @@ accelerators::ShowTaskManager(); break; case AcceleratorAction::kStartAssistant: - // TODO(longbowei): Move this to CanToggleAssistant(). - if (ShouldToggleAssistant(accelerator)) { - RecordToggleAssistant(accelerator); - accelerators::ToggleAssistant(); - } + RecordToggleAssistant(accelerator); + accelerators::ToggleAssistant(); break; case AcceleratorAction::kSuspend: base::RecordAction(UserMetricsAction("Accel_Suspend"));
diff --git a/ash/accelerators/ash_accelerator_configuration.cc b/ash/accelerators/ash_accelerator_configuration.cc index 8b441c5..0002bffd 100644 --- a/ash/accelerators/ash_accelerator_configuration.cc +++ b/ash/accelerators/ash_accelerator_configuration.cc
@@ -41,6 +41,7 @@ constexpr char kAcceleratorKeyCodeKey[] = "key"; constexpr char kAcceleratorTypeKey[] = "type"; constexpr char kAcceleratorStateKey[] = "state"; +constexpr char kAcceleratorKeyStateKey[] = "key_state"; constexpr char kAcceleratorModificationActionKey[] = "action"; PrefService* GetActiveUserPrefService() { @@ -74,6 +75,8 @@ accelerator_values.Set( kAcceleratorStateKey, static_cast<int>(ash::mojom::AcceleratorState::kEnabled)); + accelerator_values.Set(kAcceleratorKeyStateKey, + static_cast<int>(accelerator.key_state())); accelerator_values.Set(kAcceleratorModificationActionKey, static_cast<int>(action)); return base::Value(std::move(accelerator_values)); @@ -85,11 +88,16 @@ absl::optional<int> modifier = value.FindInt(kAcceleratorModifiersKey); absl::optional<int> modification_action = value.FindInt(kAcceleratorModificationActionKey); + absl::optional<int> key_state = value.FindInt(kAcceleratorKeyStateKey); CHECK(keycode.has_value()); CHECK(modifier.has_value()); CHECK(modification_action.has_value()); ui::Accelerator accelerator(static_cast<ui::KeyboardCode>(*keycode), static_cast<int>(*modifier)); + if (key_state.has_value()) { + accelerator.set_key_state( + static_cast<ui::Accelerator::KeyState>(key_state.value())); + } return {accelerator, static_cast<AcceleratorModificationAction>(*modification_action)}; }
diff --git a/ash/accelerators/ash_accelerator_configuration_unittest.cc b/ash/accelerators/ash_accelerator_configuration_unittest.cc index 5d7029513..0acd190 100644 --- a/ash/accelerators/ash_accelerator_configuration_unittest.cc +++ b/ash/accelerators/ash_accelerator_configuration_unittest.cc
@@ -37,6 +37,7 @@ constexpr char kAcceleratorModificationActionKey[] = "action"; constexpr char kAcceleratorStateKey[] = "state"; constexpr char kAcceleratorTypeKey[] = "type"; +constexpr char kAcceleratorKeyStateKey[] = "key_state"; constexpr char kFakeUserEmail[] = "fakeuser@gmail.com"; constexpr char kFakeUserEmail2[] = "fakeuser2@gmail.com"; @@ -106,21 +107,27 @@ absl::optional<int> modifier = value.FindInt(kAcceleratorModifiersKey); absl::optional<int> modification_action = value.FindInt(kAcceleratorModificationActionKey); + absl::optional<int> key_state = value.FindInt(kAcceleratorKeyStateKey); CHECK(keycode.has_value()); CHECK(modifier.has_value()); CHECK(modification_action.has_value()); - ui::Accelerator accelerator(static_cast<ui::KeyboardCode>(*keycode), - static_cast<int>(*modifier)); + CHECK(key_state.has_value()); + ui::Accelerator accelerator( + static_cast<ui::KeyboardCode>(*keycode), static_cast<int>(*modifier), + static_cast<ui::Accelerator::KeyState>(*key_state)); return {accelerator, static_cast<AcceleratorModificationAction>(*modification_action)}; } bool CompareAccelerators(const ash::AcceleratorData& expected_data, const ui::Accelerator& actual_accelerator) { - ui::Accelerator expected_accel(expected_data.keycode, - expected_data.modifiers); + ui::Accelerator expected_accel(expected_data.keycode, expected_data.modifiers, + expected_data.trigger_on_press + ? ui::Accelerator::KeyState::PRESSED + : ui::Accelerator::KeyState::RELEASED); return expected_accel.key_code() == actual_accelerator.key_code() && - expected_accel.modifiers() == actual_accelerator.modifiers(); + expected_accel.modifiers() == actual_accelerator.modifiers() && + expected_accel.key_state() == actual_accelerator.key_state(); } void ExpectAllAcceleratorsEqual( @@ -2357,4 +2364,94 @@ // Verify pref overrides were loaded correctly. ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); } + +TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorWithPrefReleasedState) { + SimulateNewUserFirstLogin(kFakeUserEmail); + const AcceleratorData test_data[] = { + {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + {/*trigger_on_press=*/true, ui::VKEY_SPACE, + ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + }; + + config_->Initialize(test_data); + + // Expect that there are no entries stored in the override pref. + const base::Value::Dict& pref_overrides = GetOverridePref(); + EXPECT_TRUE(pref_overrides.empty()); + + const ui::Accelerator released_accelerator( + ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::Accelerator::KeyState::RELEASED); + AcceleratorConfigResult result = config_->AddUserAccelerator( + AcceleratorAction::kSwitchToLastUsedIme, released_accelerator); + EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); + + const ui::Accelerator pressed_accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN, + ui::Accelerator::KeyState::PRESSED); + result = config_->AddUserAccelerator(AcceleratorAction::kSwitchToLastUsedIme, + pressed_accelerator); + + EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); + const base::Value::Dict& updated_overrides = GetOverridePref(); + // There should now be an entry in the pref overrides. + EXPECT_EQ(1u, updated_overrides.size()); + // Expect the pref to have one entry that has the key of + // `AcceleratorAction::kSwitchToLastUsedIme`. + const base::Value::List* accelerator_overrides = updated_overrides.FindList( + base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme)); + // Expect 2 overrides accelerator for + // `AcceleratorAction::kSwitchToLastUsedIme`. + EXPECT_EQ(2u, accelerator_overrides->size()); + + const AcceleratorData updated_test_data[] = { + {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + {/*trigger_on_press=*/true, ui::VKEY_SPACE, + ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + {/*trigger_on_press=*/false, ui::VKEY_A, ui::EF_COMMAND_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + {/*trigger_on_press=*/true, ui::VKEY_A, ui::EF_COMMAND_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + }; + + AcceleratorModificationData override_data = + ValueToAcceleratorModificationData( + accelerator_overrides->front().GetDict()); + EXPECT_TRUE(CompareAccelerators( + {/*trigger_on_press=*/false, ui::VKEY_A, ui::EF_COMMAND_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + override_data.accelerator)); + EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action); + + override_data = ValueToAcceleratorModificationData( + accelerator_overrides->back().GetDict()); + EXPECT_TRUE(CompareAccelerators( + {/*trigger_on_press=*/true, ui::VKEY_A, ui::EF_COMMAND_DOWN, + AcceleratorAction::kSwitchToLastUsedIme}, + override_data.accelerator)); + EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action); + + ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators()); + + // Simulate login on another account, expect the pref to not be present. + GetSessionControllerClient()->LockScreen(); + SimulateNewUserFirstLogin(kFakeUserEmail2); + const base::Value::Dict& other_user_pref_overrides = GetOverridePref(); + EXPECT_TRUE(other_user_pref_overrides.empty()); + + // Now re-login to the original profile. + GetSessionControllerClient()->LockScreen(); + config_->Initialize(test_data); + SimulateUserLogin(kFakeUserEmail); + const base::Value::Dict& original_pref_overrides = GetOverridePref(); + EXPECT_FALSE(original_pref_overrides.empty()); + + const base::Value::Dict& relogin_overrides = GetOverridePref(); + EXPECT_EQ(1u, relogin_overrides.size()); + // Verify pref overrides were loaded correctly. + ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators()); +} + } // namespace ash
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc index 89c8c77..e9bb54f 100644 --- a/ash/accessibility/accessibility_controller_impl.cc +++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -12,6 +12,7 @@ #include "ash/accelerators/accelerator_controller_impl.h" #include "ash/accessibility/a11y_feature_type.h" +#include "ash/accessibility/accessibility_notification_controller.h" #include "ash/accessibility/accessibility_observer.h" #include "ash/accessibility/autoclick/autoclick_controller.h" #include "ash/accessibility/dictation_nudge_controller.h" @@ -969,10 +970,14 @@ Shell::Get()->session_controller()->AddObserver(this); Shell::Get()->tablet_mode_controller()->AddObserver(this); CreateAccessibilityFeatures(); + + accessibility_notification_controller_ = + std::make_unique<AccessibilityNotificationController>(); } AccessibilityControllerImpl::~AccessibilityControllerImpl() { floating_menu_controller_.reset(); + accessibility_notification_controller_.reset(); } void AccessibilityControllerImpl::CreateAccessibilityFeatures() { @@ -1938,6 +1943,8 @@ void AccessibilityControllerImpl::ShowDictationLanguageUpgradedNudge( const std::string& dictation_locale, const std::string& application_locale) { + // TODO(b:259352600): Move dictation_nudge_controller_ into + // accessibility_notification_controller. dictation_nudge_controller_ = std::make_unique<DictationNudgeController>( dictation_locale, application_locale); dictation_nudge_controller_->ShowNudge(); @@ -2925,4 +2932,14 @@ return dictation_bubble_controller_.get(); } +void AccessibilityControllerImpl::ShowToast(AccessibilityToastType type) { + accessibility_notification_controller_->ShowToast(type); +} + +void AccessibilityControllerImpl::AddShowToastCallbackForTesting( + base::RepeatingClosure callback) { + accessibility_notification_controller_->AddShowToastCallbackForTesting( + std::move(callback)); +} + } // namespace ash
diff --git a/ash/accessibility/accessibility_controller_impl.h b/ash/accessibility/accessibility_controller_impl.h index 1a1551a..0b496067 100644 --- a/ash/accessibility/accessibility_controller_impl.h +++ b/ash/accessibility/accessibility_controller_impl.h
@@ -8,6 +8,7 @@ #include <memory> #include "ash/accessibility/a11y_feature_type.h" +#include "ash/accessibility/accessibility_notification_controller.h" #include "ash/ash_export.h" #include "ash/constants/ash_constants.h" #include "ash/public/cpp/accessibility_controller.h" @@ -471,6 +472,7 @@ const absl::optional<std::vector<DictationBubbleHintType>>& hints) override; void SilenceSpokenFeedback() override; + void ShowToast(AccessibilityToastType type) override; // A confirmation dialog will be shown the first time an accessibility feature // is enabled using the specified accelerator key sequence. Only one dialog @@ -534,6 +536,8 @@ OnDictationKeyboardDialogDismissed(); } + void AddShowToastCallbackForTesting(base::RepeatingClosure callback); + private: // Populate |features_| with the feature of the correct type. void CreateAccessibilityFeatures(); @@ -647,6 +651,10 @@ // Used to control the Dictation bubble UI. std::unique_ptr<DictationBubbleController> dictation_bubble_controller_; + // Used to control accessibility-related notifications. + std::unique_ptr<AccessibilityNotificationController> + accessibility_notification_controller_; + // True if ChromeVox should enable its volume slide gesture. bool enable_chromevox_volume_slide_gesture_ = false;
diff --git a/ash/accessibility/accessibility_controller_test_api_impl.cc b/ash/accessibility/accessibility_controller_test_api_impl.cc index 099087bd..d7fc792e 100644 --- a/ash/accessibility/accessibility_controller_test_api_impl.cc +++ b/ash/accessibility/accessibility_controller_test_api_impl.cc
@@ -7,6 +7,7 @@ #include "ash/accelerators/accelerator_controller_impl.h" #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/shell.h" +#include "base/functional/callback.h" namespace ash { @@ -52,6 +53,12 @@ ->DismissDictationKeyboardDialogForTesting(); // IN-TEST } +void AccessibilityControllerTestApiImpl::AddShowToastCallbackForTesting( + base::RepeatingClosure callback) const { + GetController()->AddShowToastCallbackForTesting( + std::move(callback)); // IN-TEST +} + // static std::unique_ptr<AccessibilityControllerTestApi> AccessibilityControllerTestApi::Create() {
diff --git a/ash/accessibility/accessibility_controller_test_api_impl.h b/ash/accessibility/accessibility_controller_test_api_impl.h index 4ad02f3..bfcbb16 100644 --- a/ash/accessibility/accessibility_controller_test_api_impl.h +++ b/ash/accessibility/accessibility_controller_test_api_impl.h
@@ -6,6 +6,7 @@ #define ASH_ACCESSIBILITY_ACCESSIBILITY_CONTROLLER_TEST_API_IMPL_H_ #include "ash/public/cpp/test/accessibility_controller_test_api.h" +#include "base/functional/callback_forward.h" namespace ash { @@ -14,12 +15,10 @@ : public AccessibilityControllerTestApi { public: AccessibilityControllerTestApiImpl(); - AccessibilityControllerTestApiImpl( const AccessibilityControllerTestApiImpl&) = delete; AccessibilityControllerTestApiImpl& operator=( const AccessibilityControllerTestApiImpl&) = delete; - ~AccessibilityControllerTestApiImpl() override; // AccessibilityControllerTestApi: @@ -29,6 +28,8 @@ bool IsDictationKeboardDialogShowing() const override; void AcceptDictationKeyboardDialog() override; void DismissDictationKeyboardDialog() override; + void AddShowToastCallbackForTesting( + base::RepeatingClosure callback) const override; }; } // namespace ash
diff --git a/ash/accessibility/accessibility_notification_controller.cc b/ash/accessibility/accessibility_notification_controller.cc new file mode 100644 index 0000000..90e0adb --- /dev/null +++ b/ash/accessibility/accessibility_notification_controller.cc
@@ -0,0 +1,56 @@ +// 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 "ash/accessibility/accessibility_notification_controller.h" + +#include "ash/public/cpp/accessibility_controller_enums.h" +#include "ash/public/cpp/system/toast_data.h" +#include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/toast/toast_manager_impl.h" +#include "ui/accessibility/accessibility_features.h" +#include "ui/base/l10n/l10n_util.h" + +namespace ash { + +namespace { + +const std::string kAccessibilityToastId = "AccessibilityToast"; + +ToastData GetToastData(AccessibilityToastType type) { + switch (type) { + case AccessibilityToastType::kDictationNoFocusedTextField: + return {/*id=*/kAccessibilityToastId, + /*catalog_name=*/ToastCatalogName::kDictationNoFocusedTextField, + /*text=*/ + l10n_util::GetStringUTF16( + IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD)}; + } +} + +} // namespace + +AccessibilityNotificationController::AccessibilityNotificationController() = + default; +AccessibilityNotificationController::~AccessibilityNotificationController() = + default; + +void AccessibilityNotificationController::ShowToast( + AccessibilityToastType type) { + if (!::features::IsAccessibilityDictationKeyboardImprovementsEnabled()) { + return; + } + + Shell::Get()->toast_manager()->Show(GetToastData(type)); + if (show_anchored_nudge_callback_for_testing_) { + show_anchored_nudge_callback_for_testing_.Run(); + } +} + +void AccessibilityNotificationController::AddShowToastCallbackForTesting( + base::RepeatingClosure callback) { + show_anchored_nudge_callback_for_testing_ = std::move(callback); +} + +} // namespace ash
diff --git a/ash/accessibility/accessibility_notification_controller.h b/ash/accessibility/accessibility_notification_controller.h new file mode 100644 index 0000000..366d81b --- /dev/null +++ b/ash/accessibility/accessibility_notification_controller.h
@@ -0,0 +1,33 @@ +// 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 ASH_ACCESSIBILITY_ACCESSIBILITY_NOTIFICATION_CONTROLLER_H_ +#define ASH_ACCESSIBILITY_ACCESSIBILITY_NOTIFICATION_CONTROLLER_H_ + +#include "ash/ash_export.h" +#include "ash/public/cpp/accessibility_controller_enums.h" +#include "base/functional/callback.h" + +namespace ash { + +// Class that manages showing notifications for accessibility. +class ASH_EXPORT AccessibilityNotificationController { + public: + AccessibilityNotificationController(); + AccessibilityNotificationController( + const AccessibilityNotificationController&) = delete; + AccessibilityNotificationController& operator=( + const AccessibilityNotificationController&) = delete; + ~AccessibilityNotificationController(); + + void ShowToast(AccessibilityToastType type); + void AddShowToastCallbackForTesting(base::RepeatingClosure callback); + + private: + base::RepeatingClosure show_anchored_nudge_callback_for_testing_; +}; + +} // namespace ash + +#endif // ASH_ACCESSIBILITY_ACCESSIBILITY_NOTIFICATION_CONTROLLER_H_
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index 040cf9d..09fba73 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -1680,6 +1680,7 @@ client->GetAndResetPastSearchQueries()); SearchBoxView* search_box_view = GetSearchBoxView(); + search_box_view->GetWidget()->LayoutRootViewIfNecessary(); EXPECT_TRUE(search_box_view->close_button()->GetVisible()); LeftClickOn(search_box_view->close_button());
diff --git a/ash/app_list/views/app_list_bubble_view_unittest.cc b/ash/app_list/views/app_list_bubble_view_unittest.cc index 720a5bc..1bf1761 100644 --- a/ash/app_list/views/app_list_bubble_view_unittest.cc +++ b/ash/app_list/views/app_list_bubble_view_unittest.cc
@@ -677,6 +677,7 @@ // Close button is visible after typing text. SearchBoxView* search_box_view = GetSearchBoxView(); + search_box_view->GetWidget()->LayoutRootViewIfNecessary(); EXPECT_TRUE(search_box_view->close_button()->GetVisible()); EXPECT_FALSE(search_box_view->search_box()->GetText().empty());
diff --git a/ash/app_list/views/app_list_view_pixeltest.cc b/ash/app_list/views/app_list_view_pixeltest.cc index 75e2c19..2388234 100644 --- a/ash/app_list/views/app_list_view_pixeltest.cc +++ b/ash/app_list/views/app_list_view_pixeltest.cc
@@ -362,7 +362,7 @@ TEST_P(AppListViewTabletPixelTest, Basic) { EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( "tablet_launcher_basics", - /*revision_number=*/IsJellyEnabled() ? 4 : 3, + /*revision_number=*/IsJellyEnabled() ? 5 : 4, GetAppListTestHelper()->GetAppsContainerView())); } @@ -384,7 +384,7 @@ EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( "tablet_launcher_top_gradient_zone", - /*revision_number=*/IsJellyEnabled() ? 4 : 3, + /*revision_number=*/IsJellyEnabled() ? 5 : 4, GetAppListTestHelper()->GetAppsContainerView())); } @@ -406,7 +406,7 @@ EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen( "tablet_launcher_bottom_gradient_zone", - /*revision_number=*/IsJellyEnabled() ? 4 : 3, + /*revision_number=*/IsJellyEnabled() ? 5 : 4, GetAppListTestHelper()->GetAppsContainerView())); }
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 73a923c..87b83f7 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -270,6 +270,16 @@ cros_tokens::kCrosSysOnSurfaceVariant); } + if (features::IsProductivityLauncherImageSearchEnabled()) { + views::ImageButton* filter_button = CreateFilterButton(base::BindRepeating( + &SearchBoxView::FilterButtonPressed, base::Unretained(this))); + filter_button->SetFlipCanvasOnPaintForRTLUI(false); + // TODO(crbug.com/1352636): Replace this with the l10n string. + std::u16string filter_button_label(u"Filter search categories"); + filter_button->SetAccessibleName(filter_button_label); + filter_button->SetTooltipText(filter_button_label); + } + views::ImageButton* close_button = CreateCloseButton(base::BindRepeating( &SearchBoxView::CloseButtonPressed, base::Unretained(this))); std::u16string close_button_label( @@ -527,6 +537,12 @@ views::ImageButton::STATE_NORMAL, gfx::CreateVectorIcon(chromeos::kAssistantIcon, GetSearchBoxIconSize(), button_icon_color)); + if (filter_button()) { + filter_button()->SetImage( + views::ImageButton::STATE_NORMAL, + gfx::CreateVectorIcon(kFilterIcon, GetSearchBoxIconSize(), + button_icon_color)); + } auto* focus_ring = views::FocusRing::Get(assistant_button()); focus_ring->SetOutsetFocusRingDisabled(true); focus_ring->SetColorId(GetFocusColorId(is_jelly_enabled_)); @@ -878,6 +894,11 @@ delegate_->AssistantButtonPressed(); } +// TODO(crbug.com/1352636): Implement opening the category filter bubble. +void SearchBoxView::FilterButtonPressed() { + return; +} + void SearchBoxView::UpdateSearchIcon() { const bool search_engine_is_google = AppListModelProvider::Get()->search_model()->search_engine_is_google();
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h index 78da5b8..afb4a54 100644 --- a/ash/app_list/views/search_box_view.h +++ b/ash/app_list/views/search_box_view.h
@@ -181,6 +181,9 @@ // Called when the assistant button within the search box gets pressed. void AssistantButtonPressed(); + // Called when the filter button within the search box gets pressed. + void FilterButtonPressed(); + // Updates the icon shown left of the search box texfield. void UpdateSearchIcon();
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index 36a4b511..12394732 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -285,6 +285,17 @@ EXPECT_TRUE(view()->close_button()->GetVisible()); } +// Tests that the filter button is not created if the image search feature is +// disabled. +TEST_F(SearchBoxViewTest, FilterButtonNotCreatedWithDisabledImageSearch) { + ASSERT_FALSE(features::IsProductivityLauncherImageSearchEnabled()); + EXPECT_FALSE(view()->filter_button()); + + // The filter button is still not created after typing in the search box. + KeyPress(ui::VKEY_A); + EXPECT_FALSE(view()->filter_button()); +} + // Tests that the close button is still visible after the search box is // activated (in zero state). TEST_F(SearchBoxViewTest, CloseButtonVisibleInZeroStateSearchBox) { @@ -668,6 +679,32 @@ EXPECT_TRUE(view()->assistant_button()->GetVisible()); } +class SearchBoxViewFilterButtonTest : public SearchBoxViewTest { + public: + SearchBoxViewFilterButtonTest() { + scoped_feature_list_.Reset(); + scoped_feature_list_.InitWithFeatures( + {chromeos::features::kJelly, + features::kProductivityLauncherImageSearch}, + {}); + } + SearchBoxViewFilterButtonTest(const SearchBoxViewFilterButtonTest&) = delete; + SearchBoxViewFilterButtonTest& operator=( + const SearchBoxViewFilterButtonTest&) = delete; + ~SearchBoxViewFilterButtonTest() override = default; +}; + +// Tests that the close button is invisible by default. +TEST_F(SearchBoxViewFilterButtonTest, FilterButtonInvisibleByDefault) { + EXPECT_FALSE(view()->filter_button()->GetVisible()); +} + +// Tests that the close button becomes visible after typing in the search box. +TEST_F(SearchBoxViewFilterButtonTest, FilterButtonVisibleAfterTyping) { + KeyPress(ui::VKEY_A); + EXPECT_TRUE(view()->filter_button()->GetVisible()); +} + class SearchBoxViewAutocompleteTest : public SearchBoxViewTest, public testing::WithParamInterface<bool> { public:
diff --git a/ash/app_list/views/search_result_image_view.h b/ash/app_list/views/search_result_image_view.h index 4c1ca51..c3f7b97 100644 --- a/ash/app_list/views/search_result_image_view.h +++ b/ash/app_list/views/search_result_image_view.h
@@ -70,7 +70,8 @@ raw_ptr<SearchResultImageListView, ExperimentalAsh> const list_view_; // Child pulsing block view that is used as a placeholder. - raw_ptr<PulsingBlockView, ExperimentalAsh> pulsing_block_view_ = nullptr; + raw_ptr<PulsingBlockView, DanglingUntriaged | ExperimentalAsh> + pulsing_block_view_ = nullptr; // The preferred width of the image view which is used to calculate the // preferred size. This is set by the parent container view so that the image
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 26560999..cef8a568 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1333,6 +1333,11 @@ With dictation, you can type using your voice. Press the dictation key or select the microphone icon at the bottom of the screen when you’re on a text field. Your dictation language is set to <ph name="language">$1<ex>English (United States)</ex></ph>. Speech is sent to Google for processing. You can change the dictation language anytime in Settings > Accessibility. </message> + <!-- Accessibility nudges --> + <message name="IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD" desc="Displayed in a nudge when Dictation is stopped automatically because there is no focused text field."> + Go to a text field to use Dictation + </message> + <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_VIRTUAL_KEYBOARD" desc="The label used in the accessibility menu of the system tray to toggle on/off the onscreen keyboard."> On-screen keyboard </message> @@ -2514,14 +2519,17 @@ Last desk can't be removed. </message> <message name="IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP" desc="The accessibility tooltip read by screen readers for a highlighted active desk mini_view."> - Active desk. + active desk </message> <message name="IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP" desc="The accessibility tooltip read by screen readers for a highlighted inactive desk mini_view."> - Inactive desk. + inactive desk </message> <message name="IDS_ASH_DESKS_DESK_ACCESSIBLE_NAME" desc="The full accessible desk name"> Desk: <ph name="DESK_NAME">$1</ph> </message> + <message name="IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME" desc="The full accessible desk name"> + Go to <ph name="ACTIVE_STATE">$1</ph> <ph name="DESK_NAME">$2</ph> button. + </message> <message name="IDS_ASH_DESKS_DESK_NAME_COMMIT" desc="Alert when the desk name is committed"> Desk name was changed to <ph name="DESK_NAME">$1</ph> </message> @@ -6989,10 +6997,10 @@ No thanks </message> <message name="IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT" desc="Text shown in the body of the dialog as part of the System UI Welcome Tour."> - Take a quick tour to get off to a smooth start. With 6 steps, it will just take a few minutes. + Take a quick tour to learn how to get around your Chromebook. Get up and running in 6 steps. </message> <message name="IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT" desc="Text shown as the Welcome Tour dialog title."> - Hi there. Chromebooks are a little different. + Hi there. Chromebook is a little different. </message> <message name="IDS_ASH_WELCOME_TOUR_EXPLORE_APP_BUBBLE_BODY_TEXT" desc="Text shown in the body of a help bubble anchored to the Explore app as part of the System UI Welcome Tour."> Those were the basics! Continue in Explore, our built-in app for tips and help. You’ll find tips for getting started, recommended apps, special offers, and the newest Chromebook features.
diff --git a/ash/ash_strings_grd/IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD.png.sha1 b/ash/ash_strings_grd/IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD.png.sha1 new file mode 100644 index 0000000..b37bde2 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_ACCESSIBILITY_NUDGE_DICTATION_NO_FOCUSED_TEXT_FIELD.png.sha1
@@ -0,0 +1 @@ +cc8d39b5868c8f202c7edc14eedd27e7e64855dd \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 new file mode 100644 index 0000000..b9e56f1 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1
@@ -0,0 +1 @@ +f0ab6cae002646d549b453d8462bb660fa4f46b2 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME.png.sha1 new file mode 100644 index 0000000..9b94ed2 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME.png.sha1
@@ -0,0 +1 @@ +828c0f8080f2886b58e92b5ce5de44366924f884 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 index 13f2b42..c61e9381 100644 --- a/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1 +++ b/ash/ash_strings_grd/IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP.png.sha1
@@ -1 +1 @@ -c0011f1a7d59d0e49a62cc6be9fe822a6a1cd403 \ No newline at end of file +052eae4fae5a6f4cfec48cce64759f0a3e615d7d \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT.png.sha1 b/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT.png.sha1 index bf8551f2..8a53ab7 100644 --- a/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT.png.sha1 +++ b/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_DESCRIPTION_TEXT.png.sha1
@@ -1 +1 @@ -6324a87230d4612c68739684aac8b3cb5890f147 \ No newline at end of file +91f005bedaacf5f2aad71e6d14d785516e314450 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT.png.sha1 b/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT.png.sha1 index bf8551f2..8a53ab7 100644 --- a/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT.png.sha1 +++ b/ash/ash_strings_grd/IDS_ASH_WELCOME_TOUR_DIALOG_TITLE_TEXT.png.sha1
@@ -1 +1 @@ -6324a87230d4612c68739684aac8b3cb5890f147 \ No newline at end of file +91f005bedaacf5f2aad71e6d14d785516e314450 \ No newline at end of file
diff --git a/ash/components/arc/metrics/stability_metrics_manager.h b/ash/components/arc/metrics/stability_metrics_manager.h index ff23a8e..5a0c0708 100644 --- a/ash/components/arc/metrics/stability_metrics_manager.h +++ b/ash/components/arc/metrics/stability_metrics_manager.h
@@ -57,7 +57,8 @@ ~StabilityMetricsManager(); SEQUENCE_CHECKER(sequence_checker_); - const raw_ptr<PrefService, ExperimentalAsh> local_state_; + const raw_ptr<PrefService, LeakedDanglingUntriaged | ExperimentalAsh> + local_state_; }; } // namespace arc
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 31009e78..8b32c0c4 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2778,7 +2778,7 @@ // Enables settings to be split per device. BASE_FEATURE(kInputDeviceSettingsSplit, "InputDeviceSettingsSplit", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables bug fix for dead keys on the Terminal app. // When enabled, dead keys correctly emit the 'Dead' event on key down for the
diff --git a/ash/constants/notifier_catalogs.h b/ash/constants/notifier_catalogs.h index 8082d5a..d490049 100644 --- a/ash/constants/notifier_catalogs.h +++ b/ash/constants/notifier_catalogs.h
@@ -273,7 +273,8 @@ kCopyGifToClipboardAction = 42, // [Deprecated] kVideoConferenceTrayUseWhileDisabled = 43, kBatterySaverDisabled = 44, - kMaxValue = kBatterySaverDisabled + kDictationNoFocusedTextField = 45, + kMaxValue = kDictationNoFocusedTextField }; } // namespace ash
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc index a993d789..1647fb9 100644 --- a/ash/display/cursor_window_controller.cc +++ b/ash/display/cursor_window_controller.cc
@@ -178,7 +178,10 @@ : delegate_(new CursorWindowDelegate()), is_cursor_motion_blur_enabled_( base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshEnableCursorMotionBlur)) {} + switches::kAshEnableCursorMotionBlur)), + // TODO(b/296641218): Find another way to make sure gpu process is fully + // initialized first before updating cursor view. + start_time_(base::TimeTicks::Now()) {} CursorWindowController::~CursorWindowController() { SetContainer(NULL); @@ -217,8 +220,9 @@ } bool CursorWindowController::ShouldEnableCursorCompositing() { - if (is_cursor_motion_blur_enabled_) + if (CanEnableMotionBlur()) { return true; + } if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kForceShowCursor)) { @@ -392,6 +396,24 @@ UpdateCursorVisibility(); } +void CursorWindowController::OnWindowBoundsChanged( + aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) { + DCHECK_EQ(container_, window); + + if (cursor_view_widget_) { + UpdateCursorView(); + } +} + +void CursorWindowController::OnWindowDestroying(aura::Window* window) { + DCHECK_EQ(container_, window); + + scoped_container_observer_.Reset(); +} + const aura::Window* CursorWindowController::GetContainerForTest() const { return container_; } @@ -408,6 +430,9 @@ if (container_ == container) { return; } + + scoped_container_observer_.Reset(); + container_ = container; if (!container) { cursor_window_.reset(); @@ -415,10 +440,12 @@ return; } + scoped_container_observer_.Observe(container_); + bounds_in_screen_ = display_.bounds(); rotation_ = display_.rotation(); - if (is_cursor_motion_blur_enabled_) { + if (CanEnableMotionBlur()) { UpdateCursorView(); } else { // Reusing the window does not work when the display is disconnected. @@ -539,6 +566,11 @@ } void CursorWindowController::UpdateCursorView() { + // Return if the container's size is not updated yet. + if (container_->GetBoundsInRootWindow().size() != bounds_in_screen_.size()) { + return; + } + cursor_view_widget_ = CursorView::Create(aura::Env::GetInstance()->last_mouse_location(), is_cursor_motion_blur_enabled_, container_); @@ -549,4 +581,9 @@ return delegate_->cursor_image(); } +bool CursorWindowController::CanEnableMotionBlur() const { + return is_cursor_motion_blur_enabled_ && + base::TimeTicks::Now() - start_time_ > base::Seconds(5); +} + } // namespace ash
diff --git a/ash/display/cursor_window_controller.h b/ash/display/cursor_window_controller.h index 3e208b28..56493f3 100644 --- a/ash/display/cursor_window_controller.h +++ b/ash/display/cursor_window_controller.h
@@ -32,7 +32,7 @@ // When cursor compositing is disabled, draw nothing as the native cursor is // shown. // When cursor compositing is enabled, just draw the cursor as-is. -class ASH_EXPORT CursorWindowController { +class ASH_EXPORT CursorWindowController : public aura::WindowObserver { public: class Observer : public base::CheckedObserver { public: @@ -47,7 +47,7 @@ CursorWindowController(const CursorWindowController&) = delete; CursorWindowController& operator=(const CursorWindowController&) = delete; - ~CursorWindowController(); + ~CursorWindowController() override; bool is_cursor_compositing_enabled() const { return is_cursor_compositing_enabled_; @@ -87,6 +87,13 @@ void SetCursorSize(ui::CursorSize cursor_size); void SetVisibility(bool visible); + // aura::WindowObserver: + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) override; + void OnWindowDestroying(aura::Window* window) override; + // Gets the cursor container for testing purposes. const aura::Window* GetContainerForTest() const; SkColor GetCursorColorForTest() const; @@ -115,6 +122,8 @@ const gfx::ImageSkia& GetCursorImageForTest() const; + bool CanEnableMotionBlur() const; + base::ObserverList<Observer> observers_; raw_ptr<aura::Window, DanglingUntriaged | ExperimentalAsh> container_ = @@ -150,6 +159,9 @@ views::UniqueWidgetPtr cursor_view_widget_; const bool is_cursor_motion_blur_enabled_; + base::TimeTicks start_time_; + base::ScopedObservation<aura::Window, aura::WindowObserver> + scoped_container_observer_{this}; }; } // namespace ash
diff --git a/ash/fast_ink/cursor/cursor_view.cc b/ash/fast_ink/cursor/cursor_view.cc index f4d6039..03634539 100644 --- a/ash/fast_ink/cursor/cursor_view.cc +++ b/ash/fast_ink/cursor/cursor_view.cc
@@ -4,14 +4,20 @@ #include "ash/fast_ink/cursor/cursor_view.h" +#include <memory> + #include "base/functional/bind.h" +#include "base/functional/callback.h" #include "base/memory/ptr_util.h" #include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool.h" #include "base/trace_event/trace_event.h" #include "cc/paint/paint_canvas.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" #include "ui/gfx/geometry/skia_conversions.h" +#include "ui/gfx/image/image_skia_rep_default.h" #include "ui/gfx/presentation_feedback.h" namespace ash { @@ -53,36 +59,350 @@ } // namespace //////////////////////////////////////////////////////////////////////////////// +// CursorView::Painter + +class CursorView::Painter : public viz::DelayBasedTimeSourceClient { + public: + using UpdateSurfaceCallback = + base::RepeatingCallback<void(const gfx::Rect&, const gfx::Rect&, bool)>; + + Painter(CursorView* cursor_view, + const gfx::Point& initial_location, + bool is_motion_blur_enabled) + : cursor_view_(cursor_view), + is_motion_blur_enabled_(is_motion_blur_enabled), + location_(initial_location), + pending_location_(initial_location), + ui_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), + paint_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner( + {base::TaskPriority::USER_BLOCKING, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), + stationary_timer_( + FROM_HERE, + base::Milliseconds(kStationaryDelayMs), + base::BindRepeating(&CursorView::Painter::StationaryOnPaintThread, + base::Unretained(this))) { + // Detach sequence checker for future usage on paint thread. + DETACH_FROM_SEQUENCE(paint_sequence_checker_); + } + ~Painter() override = default; + + void Init(UpdateSurfaceCallback update_surface_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); + + dsf_ = cursor_view_->GetWidget() + ->GetNativeView() + ->GetHost() + ->device_scale_factor(); + update_surface_callback_ = std::move(update_surface_callback); + } + + void Shutdown() { + DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); + + // Waits for the current paint (if any) to finish. + base::AutoLock lock(lock_); + + cursor_view_ = nullptr; + + if (time_source_) { + time_source_->SetClient(nullptr); + } + paint_task_runner_->DeleteSoon(FROM_HERE, this); + } + + void SetCursorLocation(const gfx::Point& new_location) { + // This is called from `CursorView::OnCursorLocationChanged` which could be + // either on ui thread or evdev thread. + + // base::Unretained() is safe because `this` is deleted on the paint thread. + paint_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&CursorView::Painter::SetCursorLocationOnPaintThread, + base::Unretained(this), new_location)); + } + + void SetCursorImage(const gfx::ImageSkia& cursor_image, + const gfx::Size& cursor_size, + const gfx::Point& cursor_hotspot) { + DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); + + gfx::ImageSkia scaled_cursor_image = gfx::ImageSkia::CreateFrom1xBitmap( + cursor_image.GetRepresentation(dsf_).GetBitmap()); + + // base::Unretained() is safe because `this` is deleted on the paint thread. + paint_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&CursorView::Painter::SetCursorImageOnPaintThread, + base::Unretained(this), scaled_cursor_image, cursor_size, + cursor_hotspot)); + } + + void SetTimebaseAndInterval(base::TimeTicks timebase, + base::TimeDelta interval) { + DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); + + // base::Unretained() is safe because `this` is deleted on the paint thread. + paint_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &CursorView::Painter::SetTimebaseAndIntervalOnPaintThread, + base::Unretained(this), timebase, interval)); + } + + // viz::DelayBasedTimeSourceClient overrides: + void OnTimerTick() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + + gfx::Point old_location = location_; + location_ = pending_location_; + + // Restart stationary timer if pointer location changed. + if (location_ != old_location) { + stationary_timer_.Reset(); + } + + base::TimeDelta interval = time_source_->Interval(); + // Compute velocity unless this is the first tick. + if (time_source_->LastTickTime() == next_tick_time_) { + // Velocity is pixels/second as interval might change. + velocity_ = gfx::ScaleVector2d(old_location - location_, + 1.f / interval.InSecondsF()); + velocity_.SetToMin(gfx::Vector2dF(kVelocityMax, kVelocityMax)); + } + + // Save next tick time. + next_tick_time_ = time_source_->NextTickTime(); + + // Use "Complementary Filter" algorithm to determine velocity. + // This allows us to be responsive in the short term and accurate + // in the long term. + responsive_velocity_ = InterpolateBetween(responsive_velocity_, velocity_, + kResponsiveVelocityFactor); + smooth_velocity_ = + InterpolateBetween(smooth_velocity_, velocity_, kSmoothVelocityFactor); + + // Estimate movement over one time source (VSYNC) interval. + gfx::Vector2dF movement = gfx::ScaleVector2d( + InterpolateBetween(responsive_velocity_, smooth_velocity_, + kMovementFactor), + interval.InSecondsF()); + + float distance = movement.Length(); + if (is_motion_blur_enabled_ && distance >= kMinimumMovementForMotionBlur) { + float sigma = std::min(distance / 3.f, kSigmaMax); + + // Create directional blur filter for |sigma|. + motion_blur_filter_ = sk_make_sp<cc::BlurPaintFilter>( + sigma, 0.f, SkTileMode::kDecal, nullptr); + + // Compute blur offset. + motion_blur_offset_ = + gfx::ScaleVector2d(movement, std::ceil(sigma * 3.f) / distance); + + // Determine angle of movement. + SkScalar angle = SkScalarATan2(SkFloatToScalar(movement.y()), + SkFloatToScalar(movement.x())); + SkScalar cos_angle = SkScalarCos(angle); + SkScalar sin_angle = SkScalarSin(angle); + + // Create transformation matrices for blur space. + motion_blur_matrix_.setSinCos(-sin_angle, cos_angle); + motion_blur_inverse_matrix_.setSinCos(sin_angle, cos_angle); + } else { + motion_blur_filter_.reset(); + responsive_velocity_ = gfx::Vector2dF(); + smooth_velocity_ = gfx::Vector2dF(); + time_source_->SetActive(false); + } + + // Damage is the union of old and new cursor rectangles. + gfx::Rect damage_rect = cursor_rect_; + cursor_rect_ = CalculateCursorRectOnPaintThread(); + damage_rect.Union(cursor_rect_); + + // Paint damaged area now that all parameters have been determined. + { + // Ensures that `cursor_view_` is not destructed during lifetime of + // `paint`. + base::AutoLock lock(lock_); + if (!cursor_view_) { + return; + } + + TRACE_EVENT1("ui", "CursorView::Paint", "damage_rect", + damage_rect.ToString()); + + auto paint = cursor_view_->GetScopedPaint(damage_rect); + + cc::PaintCanvas* sk_canvas = paint->canvas().sk_canvas(); + sk_canvas->translate(SkIntToScalar(location_.x() - cursor_hotspot_.x()), + SkIntToScalar(location_.y() - cursor_hotspot_.y())); + + // Undo scaling because drawing bitmaps on a scaled canvas has artifacts. + // The cursor image is scaled in `SetCursorImage` and drawn in 1x here. + sk_canvas->scale(SkFloatToScalar(1 / dsf_)); + + if (motion_blur_filter_) { + sk_canvas->translate(SkIntToScalar(motion_blur_offset_.x()), + SkIntToScalar(motion_blur_offset_.y())); + + sk_canvas->concat(SkM44(motion_blur_inverse_matrix_)); + SkRect blur_rect = SkRect::MakeWH(SkIntToScalar(cursor_size_.width()), + SkIntToScalar(cursor_size_.height())); + motion_blur_matrix_.mapRect(&blur_rect); + cc::PaintFlags flags; + flags.setImageFilter(motion_blur_filter_); + sk_canvas->saveLayer(blur_rect, flags); + sk_canvas->concat(SkM44(motion_blur_matrix_)); + paint->canvas().DrawImageInt(cursor_image_, 0, 0); + sk_canvas->restore(); + } else { + // Fast path for when motion blur is not present. + paint->canvas().DrawImageInt(cursor_image_, 0, 0); + } + } + + ui_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(update_surface_callback_, cursor_rect_, damage_rect, + /*auto_refresh=*/stationary_timer_.IsRunning())); + } + + private: + void SetCursorLocationOnPaintThread(const gfx::Point& new_location) { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + if (location_ == new_location) { + return; + } + + pending_location_ = new_location; + SetActiveOnPaintThread(true); + } + + void SetCursorImageOnPaintThread(const gfx::ImageSkia& cursor_image, + const gfx::Size& cursor_size, + const gfx::Point& cursor_hotspot) { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + + cursor_image_ = cursor_image; + cursor_size_ = cursor_size; + cursor_hotspot_ = cursor_hotspot; + + SetActiveOnPaintThread(true); + } + + void StationaryOnPaintThread() { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + + stationary_timer_.Stop(); + + ui_task_runner_->PostTask( + FROM_HERE, base::BindOnce(update_surface_callback_, cursor_rect_, + /*damage_rect=*/gfx::Rect(), + /*auto_refresh=*/false)); + } + + gfx::Rect CalculateCursorRectOnPaintThread() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + + if (cursor_size_.IsEmpty()) { + return gfx::Rect(); + } + + SkRect cursor_rect = SkRect::MakeWH(SkIntToScalar(cursor_size_.width()), + SkIntToScalar(cursor_size_.height())); + + if (motion_blur_filter_) { + // Map cursor rectangle to blur space. + motion_blur_matrix_.mapRect(&cursor_rect); + + // Expand rectangle using current blur filter. + cc::PaintFlags flags; + flags.setImageFilter(motion_blur_filter_); + DCHECK(flags.ToSkPaint().canComputeFastBounds()); + flags.ToSkPaint().computeFastBounds(cursor_rect, &cursor_rect); + + // Map rectangle back to cursor space. + motion_blur_inverse_matrix_.mapRect(&cursor_rect); + + // Add motion blur offset. + cursor_rect.offset(SkIntToScalar(motion_blur_offset_.x()), + SkIntToScalar(motion_blur_offset_.y())); + } + + cursor_rect.offset(SkIntToScalar(location_.x() - cursor_hotspot_.x()), + SkIntToScalar(location_.y() - cursor_hotspot_.y())); + + return gfx::ToEnclosingRect(gfx::SkRectToRectF(cursor_rect)); + } + + void SetActiveOnPaintThread(bool active) { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + + // Create time source if it doesn't exist. + if (!time_source_) { + time_source_ = + std::make_unique<viz::DelayBasedTimeSource>(paint_task_runner_.get()); + time_source_->SetClient(this); + } + time_source_->SetActive(active); + } + + void SetTimebaseAndIntervalOnPaintThread(base::TimeTicks timebase, + base::TimeDelta interval) { + DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); + + DCHECK(time_source_); + time_source_->SetTimebaseAndInterval( + timebase + base::Milliseconds(kVSyncOffsetMs), interval); + } + + // Ensures painter is not destructed during paint. + base::Lock lock_; + + raw_ptr<CursorView> cursor_view_; + const bool is_motion_blur_enabled_; + + float dsf_ = 1.0f; + + gfx::Point location_; + gfx::Point pending_location_; + gfx::ImageSkia cursor_image_; + gfx::Size cursor_size_; + gfx::Point cursor_hotspot_; + gfx::Rect cursor_rect_; + base::TimeTicks next_tick_time_; + gfx::Vector2dF velocity_; + gfx::Vector2dF responsive_velocity_; + gfx::Vector2dF smooth_velocity_; + sk_sp<cc::PaintFilter> motion_blur_filter_; + gfx::Vector2dF motion_blur_offset_; + SkMatrix motion_blur_matrix_; + SkMatrix motion_blur_inverse_matrix_; + + const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> paint_task_runner_; + + std::unique_ptr<viz::DelayBasedTimeSource> time_source_; + base::RetainingOneShotTimer stationary_timer_; + SEQUENCE_CHECKER(paint_sequence_checker_); + + SEQUENCE_CHECKER(ui_sequence_checker_); + UpdateSurfaceCallback update_surface_callback_; +}; + +//////////////////////////////////////////////////////////////////////////////// // CursorView, public: CursorView::CursorView(const gfx::Point& initial_location, bool is_motion_blur_enabled) - : is_motion_blur_enabled_(is_motion_blur_enabled), - ui_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), - paint_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner( - {base::TaskPriority::USER_BLOCKING, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), - new_location_(initial_location), - stationary_timer_( - FROM_HERE, - base::Milliseconds(kStationaryDelayMs), - base::BindRepeating(&CursorView::StationaryOnPaintThread, - base::Unretained(this))) { + : painter_(std::make_unique<Painter>(this, + initial_location, + is_motion_blur_enabled)), + ui_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); - // Detach sequence checker for future usage on paint thread. - DETACH_FROM_SEQUENCE(paint_sequence_checker_); - - // Create update surface callback that will be posted from paint thread - // to UI thread. - update_surface_callback_ = base::BindRepeating( - &CursorView::UpdateSurface, weak_ptr_factory_.GetWeakPtr()); - - // Create transform used to convert cursor controller coordinates to screen - // coordinates. - buffer_to_screen_transform_ = - host()->window_to_buffer_transform().GetCheckedInverse(); - ui::CursorController::GetInstance()->AddCursorObserver(this); } @@ -90,6 +410,9 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); ui::CursorController::GetInstance()->RemoveCursorObserver(this); + + // `painter_` schedules its destruction in Shutdown. + painter_.release()->Shutdown(); } // static @@ -102,245 +425,61 @@ container); } -FastInkHost::PresentationCallback CursorView::GetPresentationCallback() { - return base::BindRepeating(&CursorView::DidPresentCompositorFrame, - base::Unretained(this)); -} - void CursorView::SetCursorImage(const gfx::ImageSkia& cursor_image, const gfx::Size& cursor_size, const gfx::Point& cursor_hotspot) { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); - { - base::AutoLock lock(lock_); - - new_cursor_image_ = cursor_image; - new_cursor_size_ = cursor_size; - new_cursor_hotspot_ = cursor_hotspot; - } - - // Unretained is safe as |paint_task_runner_| uses SKIP_ON_SHUTDOWN. - paint_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&CursorView::SetActiveOnPaintThread, - base::Unretained(this), true)); + painter_->SetCursorImage(cursor_image, cursor_size, cursor_hotspot); } //////////////////////////////////////////////////////////////////////////////// // ui::CursorController::CursorObserver overrides: void CursorView::OnCursorLocationChanged(const gfx::PointF& location) { - gfx::PointF new_location_f = buffer_to_screen_transform_.MapPoint(location); + if (!buffer_to_screen_transform_) { + if (!ui_task_runner_->BelongsToCurrentThread()) { + // If it is not called from ui thread, post it to ui thread. + ui_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&CursorView::OnCursorLocationChanged, + weak_ptr_factory_.GetWeakPtr(), location)); + return; + } + // Create transform used to convert cursor controller coordinates to screen + // coordinates. + buffer_to_screen_transform_ = + this->host()->window_to_buffer_transform().GetCheckedInverse(); + } + gfx::PointF new_location_f = buffer_to_screen_transform_->MapPoint(location); gfx::Point new_location = gfx::ToRoundedPoint(new_location_f); - { - base::AutoLock lock(lock_); - - if (new_location_ == new_location) - return; - new_location_ = new_location; - } - - // Unretained is safe as |paint_task_runner_| uses SKIP_ON_SHUTDOWN. - paint_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&CursorView::SetActiveOnPaintThread, - base::Unretained(this), true)); + painter_->SetCursorLocation(new_location); } //////////////////////////////////////////////////////////////////////////////// -// viz::DelayBasedTimeSourceClient overrides: +// ash::FastInkView overrides: -void CursorView::OnTimerTick() { - DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); +FastInkHost::PresentationCallback CursorView::GetPresentationCallback() { + return base::BindRepeating(&CursorView::DidPresentCompositorFrame, + weak_ptr_factory_.GetWeakPtr()); +} - gfx::Point old_location = location_; +//////////////////////////////////////////////////////////////////////////////// +// views::View overrides: - { - base::AutoLock lock(lock_); - - location_ = new_location_; - cursor_size_ = new_cursor_size_; - cursor_image_ = new_cursor_image_; - cursor_hotspot_ = new_cursor_hotspot_; - } - - // Restart stationary timer if pointer location changed. - if (location_ != old_location) - stationary_timer_.Reset(); - - base::TimeDelta interval = time_source_->Interval(); - // Compute velocity unless this is the first tick. - if (time_source_->LastTickTime() == next_tick_time_) { - // Velocity is pixels/second as interval might change. - velocity_ = gfx::ScaleVector2d(old_location - location_, - 1.f / interval.InSecondsF()); - velocity_.SetToMin(gfx::Vector2dF(kVelocityMax, kVelocityMax)); - } - - // Save next tick time. - next_tick_time_ = time_source_->NextTickTime(); - - // Use "Complementary Filter" algorithm to determine velocity. - // This allows us to be responsive in the short term and accurate - // in the long term. - responsive_velocity_ = InterpolateBetween(responsive_velocity_, velocity_, - kResponsiveVelocityFactor); - smooth_velocity_ = - InterpolateBetween(smooth_velocity_, velocity_, kSmoothVelocityFactor); - - // Estimate movement over one time source (VSYNC) interval. - gfx::Vector2dF movement = - gfx::ScaleVector2d(InterpolateBetween(responsive_velocity_, - smooth_velocity_, kMovementFactor), - interval.InSecondsF()); - - float distance = movement.Length(); - if (is_motion_blur_enabled_ && distance >= kMinimumMovementForMotionBlur) { - float sigma = std::min(distance / 3.f, kSigmaMax); - - // Create directional blur filter for |sigma|. - motion_blur_filter_ = sk_make_sp<cc::BlurPaintFilter>( - sigma, 0.f, SkTileMode::kDecal, nullptr); - - // Compute blur offset. - motion_blur_offset_ = - gfx::ScaleVector2d(movement, std::ceil(sigma * 3.f) / distance); - - // Determine angle of movement. - SkScalar angle = SkScalarATan2(SkFloatToScalar(movement.y()), - SkFloatToScalar(movement.x())); - SkScalar cos_angle = SkScalarCos(angle); - SkScalar sin_angle = SkScalarSin(angle); - - // Create transformation matrices for blur space. - motion_blur_matrix_.setSinCos(-sin_angle, cos_angle); - motion_blur_inverse_matrix_.setSinCos(sin_angle, cos_angle); - } else { - motion_blur_filter_.reset(); - responsive_velocity_ = gfx::Vector2dF(); - smooth_velocity_ = gfx::Vector2dF(); - time_source_->SetActive(false); - } - - // Damage is the union of old and new cursor rectangles. - gfx::Rect damage_rect = cursor_rect_; - cursor_rect_ = CalculateCursorRectOnPaintThread(); - damage_rect.Union(cursor_rect_); - - // Paint damaged area now that all parameters have been determined. - { - TRACE_EVENT1("ui", "CursorView::Paint", "damage_rect", - damage_rect.ToString()); - - auto paint = GetScopedPaint(damage_rect); - - cc::PaintCanvas* sk_canvas = paint->canvas().sk_canvas(); - sk_canvas->translate(SkIntToScalar(location_.x() - cursor_hotspot_.x()), - SkIntToScalar(location_.y() - cursor_hotspot_.y())); - - if (motion_blur_filter_) { - sk_canvas->translate(SkIntToScalar(motion_blur_offset_.x()), - SkIntToScalar(motion_blur_offset_.y())); - - sk_canvas->concat(SkM44(motion_blur_inverse_matrix_)); - SkRect blur_rect = SkRect::MakeWH(SkIntToScalar(cursor_size_.width()), - SkIntToScalar(cursor_size_.height())); - motion_blur_matrix_.mapRect(&blur_rect); - cc::PaintFlags flags; - flags.setImageFilter(motion_blur_filter_); - sk_canvas->saveLayer(blur_rect, flags); - sk_canvas->concat(SkM44(motion_blur_matrix_)); - paint->canvas().DrawImageInt(cursor_image_, 0, 0); - sk_canvas->restore(); - } else { - // Fast path for when motion blur is not present. - paint->canvas().DrawImageInt(cursor_image_, 0, 0); - } - } - - ui_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(update_surface_callback_, cursor_rect_, damage_rect, - /*auto_refresh=*/stationary_timer_.IsRunning())); +void CursorView::AddedToWidget() { + painter_->Init(base::BindRepeating(&CursorView::UpdateSurface, + weak_ptr_factory_.GetWeakPtr())); } //////////////////////////////////////////////////////////////////////////////// // CursorView, private: -void CursorView::StationaryOnPaintThread() { - DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); - - stationary_timer_.Stop(); - ui_task_runner_->PostTask( - FROM_HERE, base::BindOnce(update_surface_callback_, cursor_rect_, - /*damage_rect=*/gfx::Rect(), - /*auto_refresh=*/false)); -} - -gfx::Rect CursorView::CalculateCursorRectOnPaintThread() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); - - if (cursor_size_.IsEmpty()) - return gfx::Rect(); - - SkRect cursor_rect = SkRect::MakeWH(SkIntToScalar(cursor_size_.width()), - SkIntToScalar(cursor_size_.height())); - - if (motion_blur_filter_) { - // Map curser rectangle to blur space. - motion_blur_matrix_.mapRect(&cursor_rect); - - // Expand rectangle using current blur filter. - cc::PaintFlags flags; - flags.setImageFilter(motion_blur_filter_); - DCHECK(flags.ToSkPaint().canComputeFastBounds()); - flags.ToSkPaint().computeFastBounds(cursor_rect, &cursor_rect); - - // Map rectangle back to cursor space. - motion_blur_inverse_matrix_.mapRect(&cursor_rect); - - // Add motion blur offset. - cursor_rect.offset(SkIntToScalar(motion_blur_offset_.x()), - SkIntToScalar(motion_blur_offset_.y())); - } - - cursor_rect.offset(SkIntToScalar(location_.x() - cursor_hotspot_.x()), - SkIntToScalar(location_.y() - cursor_hotspot_.y())); - - return gfx::ToEnclosingRect(gfx::SkRectToRectF(cursor_rect)); -} - -void CursorView::SetActiveOnPaintThread(bool active) { - DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); - - // Create time source if it doesn't exist. - if (!time_source_) { - time_source_ = - std::make_unique<viz::DelayBasedTimeSource>(paint_task_runner_.get()); - time_source_->SetClient(this); - } - time_source_->SetActive(active); -} - -void CursorView::SetTimebaseAndIntervalOnPaintThread(base::TimeTicks timebase, - base::TimeDelta interval) { - DCHECK_CALLED_ON_VALID_SEQUENCE(paint_sequence_checker_); - - DCHECK(time_source_); - time_source_->SetTimebaseAndInterval( - timebase + base::Milliseconds(kVSyncOffsetMs), interval); -} - void CursorView::DidPresentCompositorFrame( const gfx::PresentationFeedback& feedback) { DCHECK_CALLED_ON_VALID_SEQUENCE(ui_sequence_checker_); - // Unretained is safe as |paint_task_runner_| uses SKIP_ON_SHUTDOWN. - paint_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&CursorView::SetTimebaseAndIntervalOnPaintThread, - base::Unretained(this), feedback.timestamp, - feedback.interval)); + painter_->SetTimebaseAndInterval(feedback.timestamp, feedback.interval); } } // namespace ash
diff --git a/ash/fast_ink/cursor/cursor_view.h b/ash/fast_ink/cursor/cursor_view.h index 5a97e9ede..9341d1c 100644 --- a/ash/fast_ink/cursor/cursor_view.h +++ b/ash/fast_ink/cursor/cursor_view.h
@@ -5,6 +5,8 @@ #ifndef ASH_FAST_INK_CURSOR_CURSOR_VIEW_H_ #define ASH_FAST_INK_CURSOR_CURSOR_VIEW_H_ +#include <memory> + #include "ash/fast_ink/fast_ink_view.h" #include "base/memory/raw_ptr.h" #include "base/sequence_checker.h" @@ -14,10 +16,6 @@ #include "ui/events/ozone/chromeos/cursor_controller.h" #include "ui/views/widget/unique_widget_ptr.h" -namespace base { -class SingleThreadTaskRunner; -} // namespace base - namespace gfx { struct PresentationFeedback; } @@ -27,7 +25,6 @@ // CursorView class can be used to display a cursor image with minimal // latency/jank and optional motion blur. class CursorView : public FastInkView, - public viz::DelayBasedTimeSourceClient, public ui::CursorController::CursorObserver { public: CursorView(const CursorView&) = delete; @@ -39,7 +36,6 @@ bool is_motion_blur_enabled, aura::Window* container); - void SetCursorLocation(const gfx::Point& new_location); void SetCursorImage(const gfx::ImageSkia& cursor_image, const gfx::Size& cursor_size, const gfx::Point& cursor_hotspot); @@ -47,59 +43,30 @@ // ui::CursorController::CursorObserver overrides: void OnCursorLocationChanged(const gfx::PointF& location) override; - // viz::DelayBasedTimeSourceClient overrides: - void OnTimerTick() override; - protected: - // FastInkView override. + // ash::FastInkView overrides: FastInkHost::PresentationCallback GetPresentationCallback() override; + // views::View overrides: + void AddedToWidget() override; + private: + // Paints cursor on the paint thread. + class Painter; + CursorView(const gfx::Point& initial_location, bool is_motion_blur_enabled); - void StationaryOnPaintThread(); - gfx::Rect CalculateCursorRectOnPaintThread() const; - void SetActiveOnPaintThread(bool active); - void SetTimebaseAndIntervalOnPaintThread(base::TimeTicks timebase, - base::TimeDelta interval); void DidPresentCompositorFrame(const gfx::PresentationFeedback& feedback); // Constants that can be used on any thread. - const bool is_motion_blur_enabled_; - const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; - const scoped_refptr<base::SingleThreadTaskRunner> paint_task_runner_; - gfx::Transform buffer_to_screen_transform_; + absl::optional<gfx::Transform> buffer_to_screen_transform_; - base::Lock lock_; - // Shared state protected by |lock_|. - gfx::Point new_location_; - gfx::Size new_cursor_size_; - gfx::ImageSkia new_cursor_image_; - gfx::Point new_cursor_hotspot_; - - // Paint thread state. - gfx::Point location_; - gfx::ImageSkia cursor_image_; - gfx::Size cursor_size_; - gfx::Point cursor_hotspot_; - gfx::Rect cursor_rect_; - base::TimeTicks next_tick_time_; - gfx::Vector2dF velocity_; - gfx::Vector2dF responsive_velocity_; - gfx::Vector2dF smooth_velocity_; - sk_sp<cc::PaintFilter> motion_blur_filter_; - gfx::Vector2dF motion_blur_offset_; - SkMatrix motion_blur_matrix_; - SkMatrix motion_blur_inverse_matrix_; - std::unique_ptr<viz::DelayBasedTimeSource> time_source_; - base::RetainingOneShotTimer stationary_timer_; - base::RepeatingCallback<void(const gfx::Rect&, const gfx::Rect&, bool)> - update_surface_callback_; - SEQUENCE_CHECKER(paint_sequence_checker_); + std::unique_ptr<Painter> painter_; // UI thread state. raw_ptr<ui::Compositor, ExperimentalAsh> compositor_ = nullptr; SEQUENCE_CHECKER(ui_sequence_checker_); + const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; base::WeakPtrFactory<CursorView> weak_ptr_factory_{this}; };
diff --git a/ash/game_dashboard/game_dashboard_context_unittest.cc b/ash/game_dashboard/game_dashboard_context_unittest.cc index e219b269..e20994eb 100644 --- a/ash/game_dashboard/game_dashboard_context_unittest.cc +++ b/ash/game_dashboard/game_dashboard_context_unittest.cc
@@ -325,10 +325,7 @@ gfx::Rect toolbar_bounds = test_api_->GetToolbarWidget()->GetWindowBoundsInScreen(); ui::test::EventGenerator* event_generator = GetEventGenerator(); - // TODO (b/290696780): Update entry point to use center of toolbar once - // mouse supports dragging on buttons. - event_generator->set_current_screen_location( - gfx::Point(toolbar_bounds.x() + 1, toolbar_bounds.y() + 1)); + event_generator->set_current_screen_location(toolbar_bounds.CenterPoint()); switch (move_type) { case Movement::kMouse:
diff --git a/ash/game_dashboard/game_dashboard_toolbar_view.cc b/ash/game_dashboard/game_dashboard_toolbar_view.cc index 6d3f7cf..d1566f7 100644 --- a/ash/game_dashboard/game_dashboard_toolbar_view.cc +++ b/ash/game_dashboard/game_dashboard_toolbar_view.cc
@@ -23,7 +23,9 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/chromeos/styles/cros_tokens_color_mappings.h" +#include "ui/events/event_handler.h" #include "ui/events/keycodes/keyboard_codes_posix.h" +#include "ui/events/types/event_type.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/rect.h" #include "ui/views/background.h" @@ -98,12 +100,118 @@ } // namespace +// ToolbarDragHandler is an EventHandler that keeps track of touch and mouse +// input for the purposes of determining when dragging should occur. It also is +// responsible for passing along events to notify the toolbar when a button +// click has occurred. +class ToolbarDragHandler : public ui::EventHandler { + public: + explicit ToolbarDragHandler(GameDashboardToolbarView* toolbar_view) + : toolbar_view_(toolbar_view) {} + ~ToolbarDragHandler() override = default; + + // ui::EventHandler: + void OnMouseEvent(ui::MouseEvent* event) override { + switch (event->type()) { + case ui::ET_MOUSE_PRESSED: + potential_button_click_ = true; + break; + case ui::ET_MOUSE_DRAGGED: + if (potential_button_click_) { + // We've confirmed that the user is trying to drag rather than press a + // button in the toolbar. + potential_button_click_ = false; + is_dragging_ = true; + } + DCHECK(is_dragging_) + << "Received OnMouseDragged event but the toolbar isn't dragging."; + toolbar_view_->RepositionToolbar( + capture_mode_util::GetEventScreenLocation(*event)); + break; + case ui::ET_MOUSE_RELEASED: + potential_button_click_ = false; + if (!is_dragging_) { + // Allow the toolbar to receive this event so it can handle any button + // clicks. + return; + } + + // The toolbar was dragged, so consume this event to ensure the toolbar + // button doesn't process any button clicks. + is_dragging_ = false; + toolbar_view_->EndDraggingToolbar( + capture_mode_util::GetEventScreenLocation(*event)); + break; + default: + // Don't stop events from being received on any other mouse events. + return; + } + + event->StopPropagation(); + event->SetHandled(); + } + + void OnGestureEvent(ui::GestureEvent* event) override { + const gfx::PointF toolbar_location = + capture_mode_util::GetEventScreenLocation(*event); + + switch (event->type()) { + case ui::ET_GESTURE_SCROLL_BEGIN: + is_dragging_ = true; + break; + case ui::ET_GESTURE_SCROLL_UPDATE: + DCHECK(is_dragging_) + << "Received ET_GESTURE_SCROLL_UPDATE event but the " + "toolbar isn't dragging."; + toolbar_view_->RepositionToolbar(toolbar_location); + break; + case ui::ET_GESTURE_SCROLL_END: + DCHECK(is_dragging_) << "Received ET_GESTURE_SCROLL_END event but the " + "toolbar isn't dragging."; + is_dragging_ = false; + toolbar_view_->EndDraggingToolbar(toolbar_location); + break; + case ui::ET_GESTURE_END: + if (!is_dragging_) { + // Pass along event if it occurred outside of a dragging instance. + return; + } + is_dragging_ = false; + toolbar_view_->EndDraggingToolbar(toolbar_location); + break; + default: + // Don't stop events from being received on any other gesture events. + return; + } + + event->StopPropagation(); + event->SetHandled(); + } + + private: + // Allows this class to access `GameDashboardToolbarView` owned functions. + const raw_ptr<GameDashboardToolbarView, ExperimentalAsh> toolbar_view_; + + // Indicates whether a drag event has occurred yet within a given set of mouse + // interactions. When the `OnMousePressed` event is initially received, it's + // unknown whether dragging will occur yet. The first `OnMouseDragged` event + // confirms that the user wanted to drag the toolbar rather than click on a + // button in the toolbar. + bool potential_button_click_ = false; + + // If the toolbar view is in the dragging state. + bool is_dragging_ = false; +}; + GameDashboardToolbarView::GameDashboardToolbarView( GameDashboardContext* context) : context_(context) { DCHECK(context_); DCHECK(context_->game_window()); + drag_handler_ = std::make_unique<ToolbarDragHandler>(this); + AddPreTargetHandler(drag_handler_.get(), ui::EventTarget::Priority::kSystem); + SetOrientation(views::BoxLayout::Orientation::kVertical); SetInsideBorderInsets(gfx::Insets::VH(kPaddingHeight, kPaddingWidth)); SetBetweenChildSpacing(kBetweenChildSpacing); @@ -127,51 +235,23 @@ UpdateRecordGameButton(/*is_recording_game_window=*/false); } -bool GameDashboardToolbarView::OnMousePressed(const ui::MouseEvent& event) { - is_dragging_ = true; - return true; +void GameDashboardToolbarView::RepositionToolbar( + const gfx::PointF& event_location) { + // TODO(b/290696655): Update toolbar to move based on initial click location + // rather than the top left corner. + // Verify toolbar isn't outside game window bounds. + gfx::Rect target_bounds = + gfx::Rect(gfx::ToRoundedPoint(event_location), GetPreferredSize()); + capture_mode_util::AdjustBoundsWithinConfinedBounds( + context_->game_window()->GetBoundsInScreen(), target_bounds); + GetWidget()->SetBounds(target_bounds); } -bool GameDashboardToolbarView::OnMouseDragged(const ui::MouseEvent& event) { - DCHECK(is_dragging_) - << "Received OnMouseDragged event but the toolbar isn't dragging"; - RepositionToolbar(capture_mode_util::GetEventScreenLocation(event)); - return true; -} - -void GameDashboardToolbarView::OnMouseReleased(const ui::MouseEvent& event) { - EndDraggingToolbar(capture_mode_util::GetEventScreenLocation(event)); -} - -void GameDashboardToolbarView::OnGestureEvent(ui::GestureEvent* event) { - const gfx::PointF toolbar_location = - capture_mode_util::GetEventScreenLocation(*event); - - switch (event->type()) { - case ui::ET_GESTURE_SCROLL_BEGIN: - is_dragging_ = true; - break; - case ui::ET_GESTURE_SCROLL_UPDATE: - DCHECK(is_dragging_) << "Received ET_GESTURE_SCROLL_UPDATE event but the " - "toolbar isn't dragging."; - RepositionToolbar(toolbar_location); - break; - case ui::ET_GESTURE_SCROLL_END: - DCHECK(is_dragging_) << "Received ET_GESTURE_SCROLL_END event but the " - "toolbar isn't dragging."; - is_dragging_ = false; - EndDraggingToolbar(toolbar_location); - break; - case ui::ET_GESTURE_END: - is_dragging_ = false; - EndDraggingToolbar(toolbar_location); - break; - default: - break; - } - - event->StopPropagation(); - event->SetHandled(); +void GameDashboardToolbarView::EndDraggingToolbar( + const gfx::PointF& event_location) { + RepositionToolbar(event_location); + context_->SetToolbarSnapLocation(CalculateToolbarSnapLocation( + event_location, context_->game_window()->GetBoundsInScreen())); } bool GameDashboardToolbarView::OnKeyPressed(const ui::KeyEvent& event) { @@ -336,26 +416,6 @@ } } -void GameDashboardToolbarView::RepositionToolbar( - const gfx::PointF& event_location) { - // TODO(b/290696655): Update toolbar to move based on initial click location - // rather than the top left corner. - // Verify toolbar isn't outside game window bounds. - gfx::Rect target_bounds = - gfx::Rect(gfx::ToRoundedPoint(event_location), GetPreferredSize()); - capture_mode_util::AdjustBoundsWithinConfinedBounds( - context_->game_window()->GetBoundsInScreen(), target_bounds); - GetWidget()->SetBounds(target_bounds); -} - -void GameDashboardToolbarView::EndDraggingToolbar( - const gfx::PointF& event_location) { - is_dragging_ = false; - RepositionToolbar(event_location); - context_->SetToolbarSnapLocation(CalculateToolbarSnapLocation( - event_location, context_->game_window()->GetBoundsInScreen())); -} - BEGIN_METADATA(GameDashboardToolbarView, views::BoxLayoutView) END_METADATA
diff --git a/ash/game_dashboard/game_dashboard_toolbar_view.h b/ash/game_dashboard/game_dashboard_toolbar_view.h index 2b45dfa..3952f22 100644 --- a/ash/game_dashboard/game_dashboard_toolbar_view.h +++ b/ash/game_dashboard/game_dashboard_toolbar_view.h
@@ -6,6 +6,7 @@ #define ASH_GAME_DASHBOARD_GAME_DASHBOARD_TOOLBAR_VIEW_H_ #include "ash/ash_export.h" +#include "base/allocator/partition_allocator/pointers/raw_ptr.h" #include "ui/aura/window_observer.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/layout/box_layout_view.h" @@ -14,6 +15,7 @@ class GameDashboardContext; class IconButton; +class ToolbarDragHandler; // GameDashboardToolbarView is the movable toolbar that's attached to the game // window. It contains various quick action tiles for users to access without @@ -38,11 +40,13 @@ // `CaptureModeController` has ended a recording session or was aborted. void OnRecordingEnded(); + // Handles repositioning the toolbar view within the game window. + void RepositionToolbar(const gfx::PointF& toolbar_location); + + // Handles completion of the toolbar movement. + void EndDraggingToolbar(const gfx::PointF& toolbar_location); + // views::View: - bool OnMousePressed(const ui::MouseEvent& event) override; - bool OnMouseDragged(const ui::MouseEvent& event) override; - void OnMouseReleased(const ui::MouseEvent& event) override; - void OnGestureEvent(ui::GestureEvent* event) override; bool OnKeyPressed(const ui::KeyEvent& event) override; bool OnKeyReleased(const ui::KeyEvent& event) override; @@ -84,12 +88,6 @@ const void* key, intptr_t old) override; - // Handles repositioning the toolbar view within the game window. - void RepositionToolbar(const gfx::PointF& toolbar_location); - - // Handles completion of the toolbar movement. - void EndDraggingToolbar(const gfx::PointF& toolbar_location); - // The topmost `IconButton` in the toolbar's collection, which stays visible // in both the expanded and collapsed toolbar states. raw_ptr<IconButton, ExperimentalAsh> gamepad_button_ = nullptr; @@ -106,8 +104,8 @@ const raw_ptr<GameDashboardContext, ExperimentalAsh> context_; - // If the toolbar view is in the dragging state. - bool is_dragging_ = false; + // Handles all dragging logic for the toolbar. + std::unique_ptr<ToolbarDragHandler> drag_handler_; }; } // namespace ash
diff --git a/ash/login/ui/login_pin_input_view.h b/ash/login/ui/login_pin_input_view.h index 401f975..9a9ceb9a 100644 --- a/ash/login/ui/login_pin_input_view.h +++ b/ash/login/ui/login_pin_input_view.h
@@ -106,7 +106,8 @@ bool is_read_only_ = false; // The input field owned by this view. - raw_ptr<LoginPinInput, ExperimentalAsh> code_input_ = nullptr; + raw_ptr<LoginPinInput, DanglingUntriaged | ExperimentalAsh> code_input_ = + nullptr; // Whether the 'Return' key should trigger an unlock with an empty PIN. bool authenticate_with_empty_pin_on_return_key_ = false;
diff --git a/ash/public/cpp/accessibility_controller.h b/ash/public/cpp/accessibility_controller.h index c1f82228f..e2173b903 100644 --- a/ash/public/cpp/accessibility_controller.h +++ b/ash/public/cpp/accessibility_controller.h
@@ -210,6 +210,9 @@ // Cancels all of spoken feedback's current and queued speech immediately. virtual void SilenceSpokenFeedback() = 0; + // Shows an accessibility-related toast. + virtual void ShowToast(AccessibilityToastType type) = 0; + protected: AccessibilityController(); virtual ~AccessibilityController();
diff --git a/ash/public/cpp/accessibility_controller_enums.h b/ash/public/cpp/accessibility_controller_enums.h index 8d645ab..cd8ef4e 100644 --- a/ash/public/cpp/accessibility_controller_enums.h +++ b/ash/public/cpp/accessibility_controller_enums.h
@@ -232,6 +232,12 @@ kOnlyPumpkinDownloaded, }; +// The types of accessibility-related toasts. This enum should be kept in sync +// with chrome.accessibilityPrivate.ToastType. +enum class AccessibilityToastType { + kDictationNoFocusedTextField, +}; + } // namespace ash #endif // ASH_PUBLIC_CPP_ACCESSIBILITY_CONTROLLER_ENUMS_H_
diff --git a/ash/public/cpp/test/accessibility_controller_test_api.h b/ash/public/cpp/test/accessibility_controller_test_api.h index caf12a5e..d3546c9 100644 --- a/ash/public/cpp/test/accessibility_controller_test_api.h +++ b/ash/public/cpp/test/accessibility_controller_test_api.h
@@ -8,6 +8,7 @@ #include <memory> #include "ash/ash_export.h" +#include "base/functional/callback_forward.h" namespace ash { @@ -27,6 +28,8 @@ virtual bool IsDictationKeboardDialogShowing() const = 0; virtual void AcceptDictationKeyboardDialog() = 0; virtual void DismissDictationKeyboardDialog() = 0; + virtual void AddShowToastCallbackForTesting( + base::RepeatingClosure callback) const = 0; }; } // namespace ash
diff --git a/ash/quick_pair/scanning/scanner_broker_impl_unittest.cc b/ash/quick_pair/scanning/scanner_broker_impl_unittest.cc index 5c34808..f21efde 100644 --- a/ash/quick_pair/scanning/scanner_broker_impl_unittest.cc +++ b/ash/quick_pair/scanning/scanner_broker_impl_unittest.cc
@@ -112,7 +112,7 @@ protected: bool create_instance_ = false; - raw_ptr<FakeFastPairDiscoverableScanner, ExperimentalAsh> + raw_ptr<FakeFastPairDiscoverableScanner, DanglingUntriaged | ExperimentalAsh> fake_fast_pair_discoverable_scanner_ = nullptr; }; @@ -171,7 +171,8 @@ protected: bool create_instance_ = false; - raw_ptr<FakeFastPairNotDiscoverableScanner, ExperimentalAsh> + raw_ptr<FakeFastPairNotDiscoverableScanner, + DanglingUntriaged | ExperimentalAsh> fake_fast_pair_not_discoverable_scanner_ = nullptr; };
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 0411af29..6dc3fc5 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -112,6 +112,7 @@ "eight_files.icon", "expand_all.icon", "files_app.icon", + "filter.icon", "five_files.icon", "folder.icon", "four_files.icon",
diff --git a/ash/resources/vector_icons/filter.icon b/ash/resources/vector_icons/filter.icon new file mode 100644 index 0000000..9c4fadb --- /dev/null +++ b/ash/resources/vector_icons/filter.icon
@@ -0,0 +1,53 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 9.5f, 17, +V_LINE_TO, 12, +H_LINE_TO, 11, +R_V_LINE_TO, 1.75f, +R_H_LINE_TO, 6, +R_V_LINE_TO, 1.5f, +H_LINE_TO, 11, +V_LINE_TO, 17, +H_LINE_TO, 9.5f, +CLOSE, +MOVE_TO, 3, 15.25f, +R_V_LINE_TO, -1.5f, +R_H_LINE_TO, 5, +R_V_LINE_TO, 1.5f, +H_LINE_TO, 3, +CLOSE, +MOVE_TO, 6, 12.5f, +V_LINE_TO, 10.75f, +H_LINE_TO, 3, +R_V_LINE_TO, -1.5f, +R_H_LINE_TO, 3, +V_LINE_TO, 7.5f, +R_H_LINE_TO, 1.5f, +R_V_LINE_TO, 5, +H_LINE_TO, 6, +CLOSE, +R_MOVE_TO, 3, -1.75f, +R_V_LINE_TO, -1.5f, +R_H_LINE_TO, 8, +R_V_LINE_TO, 1.5f, +H_LINE_TO, 9, +CLOSE, +MOVE_TO, 12, 8, +V_LINE_TO, 3, +R_H_LINE_TO, 1.5f, +R_V_LINE_TO, 1.75f, +H_LINE_TO, 17, +R_V_LINE_TO, 1.5f, +R_H_LINE_TO, -3.5f, +V_LINE_TO, 8, +H_LINE_TO, 12, +CLOSE, +MOVE_TO, 3, 6.25f, +R_V_LINE_TO, -1.5f, +R_H_LINE_TO, 8, +R_V_LINE_TO, 1.5f, +H_LINE_TO, 3, +CLOSE
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index 0ee627d..25302d7 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -44,6 +44,7 @@ #include "ui/views/layout/layout_provider.h" #include "ui/views/view.h" #include "ui/views/view_class_properties.h" +#include "ui/views/view_utils.h" #include "ui/views/widget/widget.h" namespace ash { @@ -436,7 +437,7 @@ search_box_button_container_ = content_container_->AddChildView(std::make_unique<views::View>()); search_box_button_container_->SetLayoutManager( - std::make_unique<views::FillLayout>()); + std::make_unique<views::BoxLayout>()); content_container_->SetFlexForView(search_box_button_container_, 0, /*use_min_size=*/true); } @@ -483,6 +484,15 @@ return assistant_button_; } +views::ImageButton* SearchBoxViewBase::CreateFilterButton( + const base::RepeatingClosure& button_callback) { + DCHECK(!filter_button_); + filter_button_ = search_box_button_container_->AddChildView( + std::make_unique<SearchBoxImageButton>(button_callback)); + filter_button_->SetVisible(false); + return filter_button_; +} + bool SearchBoxViewBase::HasSearch() const { return !search_box_->GetText().empty(); } @@ -495,11 +505,15 @@ } views::ImageButton* SearchBoxViewBase::assistant_button() { - return static_cast<views::ImageButton*>(assistant_button_); + return views::AsViewClass<views::ImageButton>(assistant_button_); } views::ImageButton* SearchBoxViewBase::close_button() { - return static_cast<views::ImageButton*>(close_button_); + return views::AsViewClass<views::ImageButton>(close_button_); +} + +views::ImageButton* SearchBoxViewBase::filter_button() { + return views::AsViewClass<views::ImageButton>(filter_button_); } views::ImageView* SearchBoxViewBase::search_icon() { @@ -600,6 +614,9 @@ close_button_->SetEnabled(enabled); if (assistant_button_) assistant_button_->SetEnabled(enabled); + if (filter_button_) { + filter_button_->SetEnabled(enabled); + } } const char* SearchBoxViewBase::GetClassName() const { @@ -683,8 +700,14 @@ if (should_show_close_button) { MaybeFadeButtonIn(close_button_); + if (filter_button_) { + MaybeFadeButtonIn(filter_button_); + } } else { MaybeFadeButtonOut(close_button_); + if (filter_button_) { + MaybeFadeButtonOut(filter_button_); + } } if (assistant_button_) { @@ -696,9 +719,13 @@ MaybeFadeButtonOut(assistant_button_); } } + + // Explicitly call Layout as the number of the buttons showing may change. + InvalidateLayout(); } void SearchBoxViewBase::MaybeFadeButtonIn(SearchBoxImageButton* button) { + CHECK(button); if (button->GetVisible() && button->is_showing()) return; @@ -720,6 +747,7 @@ } void SearchBoxViewBase::MaybeFadeButtonOut(SearchBoxImageButton* button) { + CHECK(button); if (!button->GetVisible() || !button->is_showing()) return; @@ -808,6 +836,9 @@ close_button_->UpdateInkDropColorAndOpacity(color); if (assistant_button_) assistant_button_->UpdateInkDropColorAndOpacity(color); + if (filter_button_) { + filter_button_->UpdateInkDropColorAndOpacity(color); + } } } // namespace ash
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h index c940c4b..3efaea4 100644 --- a/ash/search_box/search_box_view_base.h +++ b/ash/search_box/search_box_view_base.h
@@ -53,7 +53,7 @@ // Creates the search box close button at the right edge of the search box. // The close button will initially be hidden. The visibility will be updated - // appropriatelly when `UpdateButtonsVisibility()` gets called. + // appropriately when `UpdateButtonsVisibility()` gets called. views::ImageButton* CreateCloseButton( const base::RepeatingClosure& button_callback); @@ -62,10 +62,19 @@ // hidden, as the buttons have the same expected position within the search // box. // The assistant button will initially be hidden. The visibility will be - // updated appropriatelly when `UpdateButtonsVisibility()` gets called. + // updated appropriately when `UpdateButtonsVisibility()` gets called. views::ImageButton* CreateAssistantButton( const base::RepeatingClosure& button_callback); + // Creates the search box category filter button at the right edge of the + // search box, where clicking on it shows a bubble for the users to select + // search categories to show. + // The filter button will initially be hidden and will be shown along with the + // close button. The visibility will be updated appropriately when + // `UpdateButtonsVisibility()` gets called. + views::ImageButton* CreateFilterButton( + const base::RepeatingClosure& button_callback); + bool HasSearch() const; // Returns the bounds to use for the view (including the shadow) given the @@ -75,6 +84,7 @@ views::ImageButton* assistant_button(); views::ImageButton* close_button(); + views::ImageButton* filter_button(); views::ImageView* search_icon(); views::Textfield* search_box() { return search_box_; } @@ -223,6 +233,7 @@ raw_ptr<SearchIconImageView, ExperimentalAsh> search_icon_ = nullptr; raw_ptr<SearchBoxImageButton, ExperimentalAsh> assistant_button_ = nullptr; raw_ptr<SearchBoxImageButton, ExperimentalAsh> close_button_ = nullptr; + raw_ptr<SearchBoxImageButton, ExperimentalAsh> filter_button_ = nullptr; raw_ptr<views::BoxLayoutView, ExperimentalAsh> text_container_ = nullptr; raw_ptr<views::Textfield, ExperimentalAsh> search_box_;
diff --git a/ash/shelf/shelf_navigation_widget.cc b/ash/shelf/shelf_navigation_widget.cc index 3e281ba8..01bd9d90 100644 --- a/ash/shelf/shelf_navigation_widget.cc +++ b/ash/shelf/shelf_navigation_widget.cc
@@ -115,7 +115,7 @@ } private: - const raw_ptr<views::View, ExperimentalAsh> view_; + const raw_ptr<views::View, LeakedDanglingUntriaged | ExperimentalAsh> view_; }; // Tracks the animation smoothness of a view's bounds animation using
diff --git a/ash/system/accessibility/accessibility_feature_pod_controller.h b/ash/system/accessibility/accessibility_feature_pod_controller.h index 40441ac..f1d2698a 100644 --- a/ash/system/accessibility/accessibility_feature_pod_controller.h +++ b/ash/system/accessibility/accessibility_feature_pod_controller.h
@@ -50,10 +50,12 @@ void UpdateTileStateIfExists(); // Unowned. - const raw_ptr<UnifiedSystemTrayController, ExperimentalAsh> tray_controller_; + const raw_ptr<UnifiedSystemTrayController, + DanglingUntriaged | ExperimentalAsh> + tray_controller_; // Owned by views hierarchy. - raw_ptr<FeatureTile, ExperimentalAsh> tile_ = nullptr; + raw_ptr<FeatureTile, DanglingUntriaged | ExperimentalAsh> tile_ = nullptr; base::WeakPtrFactory<AccessibilityFeaturePodController> weak_ptr_factory_{ this};
diff --git a/ash/system/accessibility/unified_accessibility_detailed_view_controller.h b/ash/system/accessibility/unified_accessibility_detailed_view_controller.h index 77bbb34..5b22c5d0 100644 --- a/ash/system/accessibility/unified_accessibility_detailed_view_controller.h +++ b/ash/system/accessibility/unified_accessibility_detailed_view_controller.h
@@ -46,7 +46,8 @@ private: const std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_; - raw_ptr<AccessibilityDetailedView, ExperimentalAsh> view_ = nullptr; + raw_ptr<AccessibilityDetailedView, DanglingUntriaged | ExperimentalAsh> + view_ = nullptr; }; } // namespace ash
diff --git a/ash/system/channel_indicator/channel_indicator_quick_settings_view_pixeltest.cc b/ash/system/channel_indicator/channel_indicator_quick_settings_view_pixeltest.cc index a4df3cb0..2344d6f1 100644 --- a/ash/system/channel_indicator/channel_indicator_quick_settings_view_pixeltest.cc +++ b/ash/system/channel_indicator/channel_indicator_quick_settings_view_pixeltest.cc
@@ -88,12 +88,16 @@ private: base::test::ScopedFeatureList feature_list_; - raw_ptr<TestSystemTrayClient, ExperimentalAsh> system_tray_client_ = nullptr; + raw_ptr<TestSystemTrayClient, DanglingUntriaged | ExperimentalAsh> + system_tray_client_ = nullptr; scoped_refptr<UnifiedSystemTrayModel> model_; std::unique_ptr<UnifiedSystemTrayController> controller_; std::unique_ptr<views::Widget> widget_; - raw_ptr<ChannelIndicatorQuickSettingsView, ExperimentalAsh> view_ = nullptr; - raw_ptr<QuickSettingsHeader, ExperimentalAsh> header_ = nullptr; + raw_ptr<ChannelIndicatorQuickSettingsView, + DanglingUntriaged | ExperimentalAsh> + view_ = nullptr; + raw_ptr<QuickSettingsHeader, DanglingUntriaged | ExperimentalAsh> header_ = + nullptr; }; INSTANTIATE_TEST_SUITE_P(QsRevampEnabled,
diff --git a/ash/system/channel_indicator/channel_indicator_quick_settings_view_unittest.cc b/ash/system/channel_indicator/channel_indicator_quick_settings_view_unittest.cc index 2985f89..15a07ad 100644 --- a/ash/system/channel_indicator/channel_indicator_quick_settings_view_unittest.cc +++ b/ash/system/channel_indicator/channel_indicator_quick_settings_view_unittest.cc
@@ -66,9 +66,12 @@ private: base::test::ScopedFeatureList feature_list_; - raw_ptr<TestSystemTrayClient, ExperimentalAsh> system_tray_client_ = nullptr; + raw_ptr<TestSystemTrayClient, DanglingUntriaged | ExperimentalAsh> + system_tray_client_ = nullptr; std::unique_ptr<views::Widget> widget_; - raw_ptr<ChannelIndicatorQuickSettingsView, ExperimentalAsh> view_ = nullptr; + raw_ptr<ChannelIndicatorQuickSettingsView, + DanglingUntriaged | ExperimentalAsh> + view_ = nullptr; }; // Run the `Visible` test below for each value of version_info::Channel.
diff --git a/ash/system/holding_space/holding_space_tray_child_bubble_unittest.cc b/ash/system/holding_space/holding_space_tray_child_bubble_unittest.cc index a0eee6e..8b4aa58 100644 --- a/ash/system/holding_space/holding_space_tray_child_bubble_unittest.cc +++ b/ash/system/holding_space/holding_space_tray_child_bubble_unittest.cc
@@ -75,7 +75,8 @@ views::UniqueWidgetPtr widget_; std::unique_ptr<HoldingSpaceViewDelegate> view_delegate_; - raw_ptr<HoldingSpaceTrayChildBubble, ExperimentalAsh> child_bubble_ = nullptr; + raw_ptr<HoldingSpaceTrayChildBubble, DanglingUntriaged | ExperimentalAsh> + child_bubble_ = nullptr; }; // HoldingSpaceTrayChildBubblePlaceholderTest ---------------------------------- @@ -144,8 +145,9 @@ } // Owned by view hierarchy. - raw_ptr<views::View, ExperimentalAsh> placeholder_ = nullptr; - raw_ptr<views::View, ExperimentalAsh> section_ = nullptr; + raw_ptr<views::View, DanglingUntriaged | ExperimentalAsh> placeholder_ = + nullptr; + raw_ptr<views::View, DanglingUntriaged | ExperimentalAsh> section_ = nullptr; }; INSTANTIATE_TEST_SUITE_P(All,
diff --git a/ash/system/power/power_event_observer.cc b/ash/system/power/power_event_observer.cc index 944fa85..ada456fa 100644 --- a/ash/system/power/power_event_observer.cc +++ b/ash/system/power/power_event_observer.cc
@@ -251,6 +251,8 @@ << static_cast<int>(lock_state_) << ", can_lock=" << Shell::Get()->session_controller()->CanLockScreen(); chromeos::PowerManagerClient::Get()->AddObserver(this); + chromeos::PowerManagerClient::Get()->GetSwitchStates(base::BindOnce( + &PowerEventObserver::OnGetSwitchStates, weak_factory_.GetWeakPtr())); if (Shell::Get()->session_controller()->CanLockScreen()) lock_on_suspend_usage_ = std::make_unique<LockOnSuspendUsage>(); @@ -260,6 +262,15 @@ chromeos::PowerManagerClient::Get()->RemoveObserver(this); } +void PowerEventObserver::OnGetSwitchStates( + absl::optional<chromeos::PowerManagerClient::SwitchStates> result) { + if (!result.has_value()) { + return; + } + lid_state_ = result->lid_state; + VLOG(1) << "Obtained lid state=" << static_cast<uint32_t>(lid_state_); +} + void PowerEventObserver::OnLockAnimationsComplete() { VLOG(1) << "Screen locker animations have completed, lock=" << static_cast<int>(lock_state_) << " , block_suspend_token="
diff --git a/ash/system/power/power_event_observer.h b/ash/system/power/power_event_observer.h index ebdacf47..0a16a855 100644 --- a/ash/system/power/power_event_observer.h +++ b/ash/system/power/power_event_observer.h
@@ -49,6 +49,10 @@ ~PowerEventObserver() override; + // Called by D-Bus when the current switches state is successfully obtained. + void OnGetSwitchStates( + absl::optional<chromeos::PowerManagerClient::SwitchStates> result); + // Called by the WebUIScreenLocker when all the lock screen animations have // completed. This really should be implemented via an observer but since // ash/ isn't allowed to depend on chrome/ we need to have the @@ -134,6 +138,8 @@ base::UnguessableToken block_suspend_token_; std::unique_ptr<LockOnSuspendUsage> lock_on_suspend_usage_; + + base::WeakPtrFactory<PowerEventObserver> weak_factory_{this}; }; } // namespace ash
diff --git a/ash/user_education/welcome_tour/welcome_tour_prefs.cc b/ash/user_education/welcome_tour/welcome_tour_prefs.cc index 3b3c2342..c2619d5 100644 --- a/ash/user_education/welcome_tour/welcome_tour_prefs.cc +++ b/ash/user_education/welcome_tour/welcome_tour_prefs.cc
@@ -17,9 +17,9 @@ // Constants ------------------------------------------------------------------- -constexpr char kTimeOfFirstInteractionPrefPrefix[] = +static constexpr char kTimeOfFirstInteractionPrefPrefix[] = "ash.welcome_tour.interaction_time."; -constexpr char kTimeOfFirstTourCompletion[] = +static constexpr char kTimeOfFirstTourCompletion[] = "ash.welcome_tour.completed.first_time"; static constexpr char kTimeOfFirstTourPrevention[] = "ash.welcome_tour.prevented.first_time";
diff --git a/ash/user_education/welcome_tour/welcome_tour_prefs_unittest.cc b/ash/user_education/welcome_tour/welcome_tour_prefs_unittest.cc index 0712cfa..7013549 100644 --- a/ash/user_education/welcome_tour/welcome_tour_prefs_unittest.cc +++ b/ash/user_education/welcome_tour/welcome_tour_prefs_unittest.cc
@@ -6,8 +6,9 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/ash_prefs.h" -#include "ash/test/ash_test_base.h" #include "ash/user_education/welcome_tour/welcome_tour_metrics.h" +#include "base/json/values_util.h" +#include "base/strings/strcat.h" #include "base/test/scoped_feature_list.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,49 +19,159 @@ // Aliases --------------------------------------------------------------------- +using welcome_tour_metrics::kAllInteractionsSet; using welcome_tour_metrics::kAllPreventedReasonsSet; + +using welcome_tour_metrics::Interaction; using welcome_tour_metrics::PreventedReason; // Constants ------------------------------------------------------------------- +static constexpr char kTimeOfFirstInteractionPrefPrefix[] = + "ash.welcome_tour.interaction_time."; static constexpr char kTimeOfFirstTourPrevention[] = "ash.welcome_tour.prevented.first_time"; static constexpr char kReasonForFirstTourPrevention[] = "ash.welcome_tour.prevented.first_reason"; +// Helpers --------------------------------------------------------------------- + +// Fetches the time pref associated with the first time of a given interaction. +absl::optional<base::Time> GetTimeOfFirstInteraction(PrefService* prefs, + Interaction interaction) { + auto pref_name = base::StrCat({kTimeOfFirstInteractionPrefPrefix, + welcome_tour_metrics::ToString(interaction), + ".first_time"}); + auto* pref = prefs->FindPreference(pref_name); + return pref->IsDefaultValue() ? absl::nullopt + : base::ValueToTime(pref->GetValue()); +} + } // namespace -using WelcomeTourPrefsTest = AshTestBase; +// WelcomeTourPrefsTest -------------------------------------------------------- + +// Base class for tests that verify the behavior of Welcome Tour prefs. +class WelcomeTourPrefsTest : public testing::Test { + public: + WelcomeTourPrefsTest() { + feature_list_.InitAndEnableFeature(features::kWelcomeTour); + RegisterUserProfilePrefs(pref_service_.registry(), /*country=*/"", + /*for_test=*/true); + } + + protected: + TestingPrefServiceSimple* pref_service() { return &pref_service_; } + + private: + base::test::ScopedFeatureList feature_list_; + TestingPrefServiceSimple pref_service_; +}; + +// Tests ----------------------------------------------------------------------- + +// Expects the first interaction time prefs can be set exactly once. +TEST_F(WelcomeTourPrefsTest, FirstInteraction) { + for (auto interaction : kAllInteractionsSet) { + // Should be unset by default. + EXPECT_EQ(GetTimeOfFirstInteraction(pref_service(), interaction), + absl::nullopt); + + // The first time the mark method is called, it should succeed and mark the + // time as now. + auto before = base::Time::Now(); + EXPECT_TRUE(MarkTimeOfFirstInteraction(pref_service(), interaction)); + auto after = base::Time::Now(); + + auto interaction_time = + GetTimeOfFirstInteraction(pref_service(), interaction); + ASSERT_TRUE(interaction_time); + EXPECT_GE(interaction_time, before); + EXPECT_LE(interaction_time, after); + + // For any call beyond the first, the function should return false and the + // marked time should not change. + EXPECT_FALSE(MarkTimeOfFirstInteraction(pref_service(), interaction)); + EXPECT_EQ(GetTimeOfFirstInteraction(pref_service(), interaction), + interaction_time); + } +} + +// Expects the first tour completion time pref can be set exactly once. +TEST_F(WelcomeTourPrefsTest, FirstTourCompletion) { + // Should be unset by default. + EXPECT_EQ(GetTimeOfFirstTourCompletion(pref_service()), absl::nullopt); + + // The first time the mark method is called, it should succeed and mark the + // time as now. + auto before = base::Time::Now(); + EXPECT_TRUE(MarkTimeOfFirstTourCompletion(pref_service())); + auto after = base::Time::Now(); + + auto completion_time = GetTimeOfFirstTourCompletion(pref_service()); + ASSERT_TRUE(completion_time); + EXPECT_GE(completion_time, before); + EXPECT_LE(completion_time, after); + + // For any call beyond the first, the function should return false and the + // marked time should not change. + EXPECT_FALSE(MarkTimeOfFirstTourCompletion(pref_service())); + EXPECT_EQ(GetTimeOfFirstTourCompletion(pref_service()), completion_time); +} + +// Expects the first tour prevention time pref and reason pref can be set +// exactly once. +TEST_F(WelcomeTourPrefsTest, FirstTourPrevention) { + // Should be unset by default. + EXPECT_EQ(GetReasonForFirstTourPrevention(pref_service()), absl::nullopt); + EXPECT_EQ(GetTimeOfFirstTourPrevention(pref_service()), absl::nullopt); + + // The first time the mark method is called, it should succeed and mark the + // time as now and the given reason as the reason. + auto before = base::Time::Now(); + EXPECT_TRUE( + MarkFirstTourPrevention(pref_service(), PreventedReason::kMaxValue)); + auto after = base::Time::Now(); + + EXPECT_EQ(GetReasonForFirstTourPrevention(pref_service()), + PreventedReason::kMaxValue); + + auto prevention_time = GetTimeOfFirstTourPrevention(pref_service()); + ASSERT_TRUE(prevention_time); + EXPECT_GE(prevention_time, before); + EXPECT_LE(prevention_time, after); + + // For any call beyond the first, the function should return false and the + // marked time and reason should not change. + EXPECT_FALSE(MarkFirstTourPrevention(pref_service(), + PreventedReason::kChromeVoxEnabled)); + EXPECT_EQ(GetReasonForFirstTourPrevention(pref_service()), + PreventedReason::kMaxValue); + EXPECT_EQ(GetTimeOfFirstTourPrevention(pref_service()), prevention_time); +} // Expects that setting and fetching the reason for first tour prevention will // work for all valid values, and handle invalid ones properly. TEST_F(WelcomeTourPrefsTest, ReasonForFirstTourPrevention) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kWelcomeTour); - - auto prefs = std::make_unique<TestingPrefServiceSimple>(); - RegisterUserProfilePrefs(prefs->registry(), /*country=*/"", - /*for_test=*/true); - // The reason should by default be absent. - EXPECT_EQ(GetReasonForFirstTourPrevention(prefs.get()), absl::nullopt); + EXPECT_EQ(GetReasonForFirstTourPrevention(pref_service()), absl::nullopt); // Expect that all valid values for `PreventedReason` can be set and fetched. for (auto reason : kAllPreventedReasonsSet) { - MarkFirstTourPrevention(prefs.get(), reason); - EXPECT_EQ(GetReasonForFirstTourPrevention(prefs.get()), reason); + MarkFirstTourPrevention(pref_service(), reason); + EXPECT_EQ(GetReasonForFirstTourPrevention(pref_service()), reason); // Clear the time pref for the next loop. `MarkFirstTourPrevention()` would // exit early otherwise. - prefs->ClearPref(kTimeOfFirstTourPrevention); + pref_service()->ClearPref(kTimeOfFirstTourPrevention); } // For any values that are out of bounds of the enum, it should default to // `PreventedReason::kUnknown`. - prefs->SetUserPref( + pref_service()->SetUserPref( kReasonForFirstTourPrevention, base::Value(static_cast<int>(PreventedReason::kMaxValue) + 1)); - EXPECT_EQ(GetReasonForFirstTourPrevention(prefs.get()), + EXPECT_EQ(GetReasonForFirstTourPrevention(pref_service()), PreventedReason::kUnknown); }
diff --git a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom index 519c082..86739bda 100644 --- a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom +++ b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom
@@ -8,6 +8,7 @@ import "ash/public/mojom/accelerator_info.mojom"; import "ash/public/mojom/accelerator_keys.mojom"; import "mojo/public/mojom/base/string16.mojom"; +import "ui/base/accelerators/mojom/accelerator.mojom"; // A struct that is returned from modifying an accelerator. It contains // an optional field for the accelerator name if the action has a conflict with @@ -22,12 +23,13 @@ ash.mojom.AcceleratorConfigResult result; }; -// Represents an accelerator with only the KeyCode and Modifier. This struct -// should only be used for sending data from the renderer to the browser -// process. +// Represents an accelerator with only the KeyCode, Modifier, and key state. +// This struct should only be used for sending data from the renderer to the +// browser process. struct SimpleAccelerator { ash.mojom.VKey key_code; int32 modifiers; + ui.mojom.AcceleratorKeyState key_state; }; // Observer interface, to be implemented by the Shortcut Customization SWA to
diff --git a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.cc b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.cc index def77a2a..fcceaf85 100644 --- a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.cc +++ b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.cc
@@ -36,6 +36,12 @@ return accelerator.modifiers() & kModifierMask; } +ui::Accelerator::KeyState +StructTraits<ash::shortcut_customization::mojom::SimpleAcceleratorDataView, + ui::Accelerator>::key_state(const ui::Accelerator& accelerator) { + return accelerator.key_state(); +} + bool StructTraits<ash::shortcut_customization::mojom::SimpleAcceleratorDataView, ui::Accelerator>:: Read(ash::shortcut_customization::mojom::SimpleAcceleratorDataView data, @@ -45,7 +51,12 @@ return false; } - *out = ui::Accelerator(keycode, data.modifiers() & kModifierMask); + ui::Accelerator::KeyState key_state; + if (!data.ReadKeyState(&key_state)) { + return false; + } + + *out = ui::Accelerator(keycode, data.modifiers() & kModifierMask, key_state); return true; }
diff --git a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.h b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.h index f7f82aac..5953b1ab 100644 --- a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.h +++ b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits.h
@@ -18,6 +18,8 @@ ui::Accelerator> { static ui::KeyboardCode key_code(const ui::Accelerator& accelerator); static int modifiers(const ui::Accelerator& accelerator); + static ui::Accelerator::KeyState key_state( + const ui::Accelerator& accelerator); static bool Read( ash::shortcut_customization::mojom::SimpleAcceleratorDataView data,
diff --git a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits_unittest.cc b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits_unittest.cc index d79c186..7b8b5c1 100644 --- a/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits_unittest.cc +++ b/ash/webui/shortcut_customization_ui/mojom/shortcut_customization_mojom_traits_unittest.cc
@@ -22,7 +22,8 @@ TEST_F(ShortcutCustomizationStructTraitsTest, SerializeAndDeserializeValidModifiers) { - ui::Accelerator accelerator(ui::KeyboardCode::VKEY_TAB, ui::EF_CONTROL_DOWN); + ui::Accelerator accelerator(ui::KeyboardCode::VKEY_TAB, ui::EF_CONTROL_DOWN, + ui::Accelerator::KeyState::RELEASED); ui::Accelerator deserialized; ASSERT_TRUE(SimpleAccelerator::Deserialize( SimpleAccelerator::Serialize(&accelerator), &deserialized));
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_view.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_view.ts index b1db04e..300c837d 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_view.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_view.ts
@@ -21,7 +21,7 @@ import {AcceleratorViewElement, ViewState} from './accelerator_view.js'; import {FakeShortcutProvider} from './fake_shortcut_provider.js'; import {getShortcutProvider} from './mojo_interface_provider.js'; -import {Accelerator, AcceleratorConfigResult, AcceleratorSource, AcceleratorState, AcceleratorType, ShortcutProviderInterface, StandardAcceleratorInfo} from './shortcut_types.js'; +import {Accelerator, AcceleratorConfigResult, AcceleratorKeyState, AcceleratorSource, AcceleratorState, AcceleratorType, ShortcutProviderInterface, StandardAcceleratorInfo} from './shortcut_types.js'; import {getAccelerator} from './shortcut_utils.js'; export type RequestUpdateAcceleratorEvent = @@ -36,6 +36,7 @@ const accelerator: Accelerator = { modifiers: 0, keyCode: 0, + keyState: AcceleratorKeyState.PRESSED, }; const standardAcceleratorInfoState: StandardAcceleratorInfo = {
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 3252cea2..753d172e 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
@@ -16,6 +16,7 @@ const sanitizedAccelerator: Accelerator = { keyCode: layoutProperties.standardAccelerator.accelerator.keyCode, modifiers: layoutProperties.standardAccelerator.accelerator.modifiers, + keyState: layoutProperties.standardAccelerator.accelerator.keyState, }; const originalAccelerator = layoutProperties.standardAccelerator?.originalAccelerator; @@ -24,6 +25,7 @@ sanitizedOriginalAccelerator = { keyCode: originalAccelerator.keyCode, modifiers: originalAccelerator.modifiers, + keyState: layoutProperties.standardAccelerator.accelerator.keyState, }; }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts index 7da0595b..4e7902e 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
@@ -20,7 +20,7 @@ import {keyToIconNameMap} from './input_key.js'; import {getShortcutProvider} from './mojo_interface_provider.js'; import {ModifierKeyCodes} from './shortcut_input.js'; -import {Accelerator, AcceleratorConfigResult, AcceleratorSource, AcceleratorState, Modifier, ShortcutProviderInterface, StandardAcceleratorInfo} from './shortcut_types.js'; +import {Accelerator, AcceleratorConfigResult, AcceleratorKeyState, AcceleratorSource, AcceleratorState, Modifier, ShortcutProviderInterface, StandardAcceleratorInfo} from './shortcut_types.js'; import {createEmptyAcceleratorInfo, getAccelerator, getModifiersForAcceleratorInfo, isCustomizationDisabled, isFunctionKey, isStandardAcceleratorInfo, keyCodeToModifier, LWIN_KEY, META_KEY, unidentifiedKeyCodeToKey} from './shortcut_utils.js'; export interface AcceleratorViewElement { @@ -427,7 +427,11 @@ * Converts a keystroke event to an Accelerator Object. */ private keystrokeToAccelerator(e: KeyboardEvent): Accelerator { - const output: Accelerator = {modifiers: 0, keyCode: 0}; + const output: Accelerator = { + modifiers: 0, + keyCode: 0, + keyState: AcceleratorKeyState.PRESSED, + }; if (e.metaKey) { output.modifiers = output.modifiers | Modifier.COMMAND; }
diff --git a/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts b/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts index af6c047..be5a297 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/fake_data.ts
@@ -6,7 +6,7 @@ import {TimeTicks} from 'chrome://resources/mojo/mojo/public/mojom/base/time.mojom-webui.js'; import {keyToIconNameMap} from './input_key.js'; -import {Accelerator, AcceleratorCategory, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, LayoutStyle, Modifier, MojoAcceleratorConfig, MojoAcceleratorInfo, MojoLayoutInfo, MojoSearchResult, TextAcceleratorPartType} from './shortcut_types.js'; +import {Accelerator, AcceleratorCategory, AcceleratorKeyState, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, LayoutStyle, Modifier, MojoAcceleratorConfig, MojoAcceleratorInfo, MojoLayoutInfo, MojoSearchResult, TextAcceleratorPartType} from './shortcut_types.js'; const fakeTimestamp: TimeTicks = { internalValue: BigInt(0), @@ -458,10 +458,12 @@ { modifiers: Modifier.COMMAND | Modifier.SHIFT, keyCode: 187, + keyState: AcceleratorKeyState.PRESSED, }, { modifiers: Modifier.CONTROL, keyCode: 84, + keyState: AcceleratorKeyState.PRESSED, }, ];
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts b/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts index 14dc2e9..88d74d62 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/shortcut_types.ts
@@ -59,6 +59,9 @@ export type AcceleratorState = AcceleratorInfoTypes.AcceleratorState; export const AcceleratorState = AcceleratorInfoTypes.AcceleratorState; +export type AcceleratorKeyState = AcceleratorTypes.AcceleratorKeyState; +export const AcceleratorKeyState = AcceleratorTypes.AcceleratorKeyState; + /** * Enumeration of accelerator config results from adding/replacing/removing an * accelerator. @@ -71,11 +74,11 @@ /** * Type alias for Accelerator. * - * The Pick utility type is used here because only `keyCode` and `modifiers` - * are necessary for this app. + * The Pick utility type is used here because only `keyCode`, `modifiers`, and + * `keyState` are necessary for this app. */ export type Accelerator = - Pick<AcceleratorTypes.Accelerator, 'keyCode'|'modifiers'>; + Pick<AcceleratorTypes.Accelerator, 'keyCode'|'modifiers'|'keyState'>; export type MojoAccelerator = AcceleratorTypes.Accelerator;
diff --git a/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts b/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts index fce820b..d510e236 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/shortcut_utils.ts
@@ -7,7 +7,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; -import {Accelerator, AcceleratorCategory, AcceleratorId, AcceleratorInfo, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, Modifier, MojoAcceleratorInfo, MojoSearchResult, StandardAcceleratorInfo, TextAcceleratorInfo} from './shortcut_types.js'; +import {Accelerator, AcceleratorCategory, AcceleratorId, AcceleratorInfo, AcceleratorKeyState, AcceleratorSource, AcceleratorState, AcceleratorSubcategory, AcceleratorType, Modifier, MojoAcceleratorInfo, MojoSearchResult, StandardAcceleratorInfo, TextAcceleratorInfo} from './shortcut_types.js'; // TODO(jimmyxgong): ChromeOS currently supports up to F24 but can be updated to // F32. Update here when F32 is available. @@ -54,10 +54,16 @@ // of MojoAccelerators, and MojoAccelerators have properties that error // when they're stringified. Due to TypeScript's structural typing, we // can't prevent MojoAccelerators from being passed to this function. - const accelAComparable: - Accelerator = {keyCode: accelA.keyCode, modifiers: accelA.modifiers}; - const accelBComparable: - Accelerator = {keyCode: accelB.keyCode, modifiers: accelB.modifiers}; + const accelAComparable: Accelerator = { + keyCode: accelA.keyCode, + modifiers: accelA.modifiers, + keyState: accelA.keyState, + }; + const accelBComparable: Accelerator = { + keyCode: accelB.keyCode, + modifiers: accelB.modifiers, + keyState: accelB.keyState, + }; return JSON.stringify(accelAComparable) === JSON.stringify(accelBComparable); }; @@ -88,7 +94,8 @@ }; export const createEmptyAcceleratorInfo = (): StandardAcceleratorInfo => { - return createEmptyAccelInfoFromAccel({modifiers: 0, keyCode: 0}); + return createEmptyAccelInfoFromAccel( + {modifiers: 0, keyCode: 0, keyState: AcceleratorKeyState.PRESSED}); }; export const getAcceleratorId =
diff --git a/ash/wm/desks/desk.h b/ash/wm/desks/desk.h index feedccdf..2c170f8 100644 --- a/ash/wm/desks/desk.h +++ b/ash/wm/desks/desk.h
@@ -81,7 +81,7 @@ // used to support per-desk z-orders for all-desk windows. Entries are stored // in ascending `order`. struct AllDeskWindowStackingData { - raw_ptr<aura::Window, ExperimentalAsh> window = nullptr; + raw_ptr<aura::Window, DanglingUntriaged | ExperimentalAsh> window = nullptr; // The z-order of the window. // Note: this is reversed from how child windows are ordered in // `aura::Window`, so an entry with `order == 0` means topmost.
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc index 3f23410..f1dd6c5 100644 --- a/ash/wm/desks/desk_mini_view.cc +++ b/ash/wm/desks/desk_mini_view.cc
@@ -505,39 +505,6 @@ desk_name_view_->GetPreferredSize().height()}; } -void DeskMiniView::GetAccessibleNodeData(ui::AXNodeData* node_data) { - desk_preview_->GetAccessibleNodeData(node_data); - - // Note that the desk may have already been destroyed. - if (desk_) { - // Announce desk name. - node_data->AddStringAttribute( - ax::mojom::StringAttribute::kName, - l10n_util::GetStringFUTF8(IDS_ASH_DESKS_DESK_ACCESSIBLE_NAME, - desk_->name())); - - node_data->AddStringAttribute( - ax::mojom::StringAttribute::kValue, - l10n_util::GetStringUTF8( - desk_->is_active() - ? IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP - : IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP)); - } - - // If the desk can be combined or closed, add a tip to let the user know they - // can use an accelerator. - if (!DesksController::Get()->CanRemoveDesks()) - return; - - const std::u16string target_desk_name = - DesksController::Get()->GetCombineDesksTargetName(desk_); - const std::string extra_tip = l10n_util::GetStringFUTF8( - IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP, target_desk_name); - - node_data->AddStringAttribute(ax::mojom::StringAttribute::kDescription, - extra_tip); -} - void DeskMiniView::OnThemeChanged() { views::View::OnThemeChanged(); UpdateFocusColor();
diff --git a/ash/wm/desks/desk_mini_view.h b/ash/wm/desks/desk_mini_view.h index a7d58aaa..652a4f5 100644 --- a/ash/wm/desks/desk_mini_view.h +++ b/ash/wm/desks/desk_mini_view.h
@@ -138,7 +138,6 @@ const char* GetClassName() const override; void Layout() override; gfx::Size CalculatePreferredSize() const override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void OnThemeChanged() override; // Desk::Observer:
diff --git a/ash/wm/desks/desk_preview_view.cc b/ash/wm/desks/desk_preview_view.cc index 4d67d933..4496207 100644 --- a/ash/wm/desks/desk_preview_view.cc +++ b/ash/wm/desks/desk_preview_view.cc
@@ -10,6 +10,7 @@ #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" #include "ash/style/style_util.h" #include "ash/wallpaper/views/wallpaper_base_view.h" #include "ash/wm/desks/desk.h" @@ -33,6 +34,7 @@ #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/wm/features.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/color/color_provider.h" #include "ui/compositor/layer.h" @@ -504,6 +506,35 @@ views::Button::GetAccessibleNodeData(node_data); if (GetAccessibleName().empty()) node_data->SetNameExplicitlyEmpty(); + + // Note that the desk may have already been destroyed. + Desk* desk = mini_view_->desk(); + if (desk) { + // Announce desk name. + node_data->AddStringAttribute( + ax::mojom::StringAttribute::kRoleDescription, + l10n_util::GetStringFUTF8( + IDS_ASH_DESKS_DESK_PREVIEW_A11Y_NAME, + l10n_util::GetStringUTF16( + desk->is_active() + ? IDS_ASH_DESKS_ACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP + : IDS_ASH_DESKS_INACTIVE_DESK_MINIVIEW_A11Y_EXTRA_TIP), + desk->name())); + } + + // If the desk can be combined or closed, add a tip to let the user know they + // can use an accelerator. + if (!DesksController::Get()->CanRemoveDesks()) { + return; + } + + const std::u16string target_desk_name = + DesksController::Get()->GetCombineDesksTargetName(desk); + const std::string extra_tip = l10n_util::GetStringFUTF8( + IDS_ASH_OVERVIEW_CLOSABLE_DESK_MINIVIEW_A11Y_EXTRA_TIP, target_desk_name); + + node_data->AddStringAttribute(ax::mojom::StringAttribute::kDescription, + extra_tip); } void DeskPreviewView::Layout() {
diff --git a/ash/wm/desks/desk_preview_view.h b/ash/wm/desks/desk_preview_view.h index e258f38..ddd8954e 100644 --- a/ash/wm/desks/desk_preview_view.h +++ b/ash/wm/desks/desk_preview_view.h
@@ -137,7 +137,8 @@ private: friend class DesksTestApi; - const raw_ptr<DeskMiniView, ExperimentalAsh> mini_view_; + const raw_ptr<DeskMiniView, LeakedDanglingUntriaged | ExperimentalAsh> + mini_view_; // A view that paints the wallpaper in the mini_view. It avoids the dimming // and blur overview mode adds to the original wallpaper. Owned by the views
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 50b0dc13..a7822b8c 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -1413,10 +1413,7 @@ split_view_divider_->UpdateDividerBounds(); previous_event_location_ = location_in_screen; - accumulated_drag_time_ticks_ = base::TimeTicks::Now(); - accumulated_drag_distance_ = 0; - - tablet_resize_mode_ = TabletResizeMode::kNormal; + StartTabletResize(); for (aura::Window* window : {primary_window_, secondary_window_}) { if (window == nullptr) { @@ -1477,15 +1474,6 @@ // This updates `tablet_resize_mode_` based on drag speed. UpdateTabletResizeMode(base::TimeTicks::Now(), modified_location_in_screen); - // If we are in the fast mode, start a timer that automatically invokes - // `ResizeWithDivider()` after a timeout. This ensure that we can switch back - // to the normal mode if the user stops dragging. Note: if the timer is - // already active, this will simply move the deadline forward. - if (tablet_resize_mode_ == TabletResizeMode::kFast) { - resize_timer_.Start(FROM_HERE, kSplitViewChunkTime, this, - &SplitViewController::OnResizeTimer); - } - // Update `divider_position_`. UpdateDividerPosition(modified_location_in_screen); NotifyDividerPositionChanged(); @@ -1515,8 +1503,7 @@ // TODO(xdai): Use fade out animation instead of just removing it. black_scrim_layer_.reset(); - resize_timer_.Stop(); - tablet_resize_mode_ = TabletResizeMode::kNormal; + EndTabletResize(); is_resizing_with_divider_ = false; const gfx::Rect work_area_bounds = @@ -3105,10 +3092,19 @@ } } -void SplitViewController::EndResizeWithDividerImpl() { - DCHECK(InSplitViewMode()); - DCHECK(!is_resizing_with_divider_); +void SplitViewController::StartTabletResize() { + accumulated_drag_time_ticks_ = base::TimeTicks::Now(); + accumulated_drag_distance_ = 0; + tablet_resize_mode_ = TabletResizeMode::kNormal; +} + +void SplitViewController::EndTabletResize() { + resize_timer_.Stop(); + tablet_resize_mode_ = TabletResizeMode::kNormal; +} + +void SplitViewController::EndTabletResizeImpl() { // The backdrop layers are removed here (rather than in // `EndResizeWithDivider()`) since they may be used while the divider is // animating to a snapped position. @@ -3118,6 +3114,13 @@ // Resize may not end with `EndResizeWithDivider()`, so make sure to clear // here too. resize_timer_.Stop(); +} + +void SplitViewController::EndResizeWithDividerImpl() { + DCHECK(InSplitViewMode()); + DCHECK(!is_resizing_with_divider_); + + EndTabletResizeImpl(); presentation_time_recorder_.reset(); RestoreWindowsTransformAfterResizing(); FinishWindowResizing(primary_window_); @@ -3157,6 +3160,15 @@ accumulated_drag_time_ticks_ = event_time_ticks; accumulated_drag_distance_ = 0; } + + // If we are in the fast mode, start a timer that automatically invokes + // `ResizeWithDivider()` after a timeout. This ensure that we can switch back + // to the normal mode if the user stops dragging. Note: if the timer is + // already active, this will simply move the deadline forward. + if (tablet_resize_mode_ == TabletResizeMode::kFast) { + resize_timer_.Start(FROM_HERE, kSplitViewChunkTime, this, + &SplitViewController::OnResizeTimer); + } } void SplitViewController::EndWindowDragImpl(
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index 66d16d1..eae7805 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -618,6 +618,15 @@ // snapped windows. void FinishWindowResizing(aura::Window* window); + // Starts performant resize for tablet mode. + void StartTabletResize(); + + // Ends performant resize for tablet mode. + void EndTabletResize(); + + // Finalizes and cleans up performant resize for tablet mode. + void EndTabletResizeImpl(); + // Finalizes and cleans up divider dragging/animating. Called when the divider // snapping animation completes or is interrupted or totally skipped. void EndResizeWithDividerImpl();
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc index a07bfc56..55ed7444 100644 --- a/ash/wm/workspace/phantom_window_controller.cc +++ b/ash/wm/workspace/phantom_window_controller.cc
@@ -16,6 +16,7 @@ #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h" +#include "ui/compositor/presentation_time_recorder.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/screen.h" #include "ui/gfx/canvas.h" @@ -75,6 +76,9 @@ constexpr base::TimeDelta kMaximizeCueAnimationDelayMs = base::Milliseconds(100); +constexpr char kShowPresentationHistogramName[] = + "Ash.PhantomWindowController.Show.PresentationTime"; + } // namespace // PhantomWindowController ---------------------------------------------------- @@ -105,11 +109,15 @@ floor((start_bounds_in_screen.height() - start_height) / 2.0f), floor((start_bounds_in_screen.width() - start_width) / 2.0f))); + aura::Window* root = + window_util::GetRootWindowMatching(target_bounds_in_screen_); + auto presentation_time_recorder = CreatePresentationTimeHistogramRecorder( + root->layer()->GetCompositor(), kShowPresentationHistogramName); + presentation_time_recorder->RequestNext(); + // Create a phantom widget with starting size so `ShowPhantomWidget()` can // animate from that current size to |target_bounds_in_screen|. - phantom_widget_ = CreatePhantomWidget( - window_util::GetRootWindowMatching(target_bounds_in_screen_), - start_bounds_in_screen); + phantom_widget_ = CreatePhantomWidget(root, start_bounds_in_screen); ShowPhantomWidget(); }
diff --git a/ash/wm_mode/pie_menu_view.h b/ash/wm_mode/pie_menu_view.h index c5db804..14bc157 100644 --- a/ash/wm_mode/pie_menu_view.h +++ b/ash/wm_mode/pie_menu_view.h
@@ -128,7 +128,7 @@ // The delegate of this view which takes care of handling button presses. Not // null. - const raw_ptr<Delegate, ExperimentalAsh> delegate_; + const raw_ptr<Delegate, DanglingUntriaged | ExperimentalAsh> delegate_; // The container hosting the buttons on the main menu of this view. When this // is visible, `active_sub_menus_stack_` should be empty, and `back_button_`
diff --git a/base/debug/debug.gni b/base/debug/debug.gni index a40b4d4..f8419e42 100644 --- a/base/debug/debug.gni +++ b/base/debug/debug.gni
@@ -13,9 +13,8 @@ # where the memory which was invalidly accessed was allocated or freed. # # Although it should work on other platforms as well, for the above reasons, - # we currently support it only for Android when compiling for Arm64. - # TODO(keishi): Reenable once merged to M117 branch. - build_allocation_stack_trace_recorder = false + # we currently enable it only for Android when compiling for Arm64. + build_allocation_stack_trace_recorder = current_cpu == "arm64" && is_android } declare_args() {
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index e4e04f2e..0ee209f 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -180,7 +180,6 @@ class SourceStream; class VideoFrameResourceProvider; class WebRtcVideoFrameAdapter; -class LegacyWebRtcVideoFrameAdapter; class VideoTrackRecorderImplContextProvider; class WorkerThread; namespace scheduler { @@ -232,7 +231,6 @@ class RenderProcessHost; class RenderWidgetHostViewMac; class RendererBlinkPlatformImpl; -class RTCVideoDecoder; class SandboxHostLinux; class ScopedAllowWaitForDebugURL; class ServiceWorkerContextClient; @@ -283,9 +281,6 @@ namespace font_service::internal { class MappedFontFile; } -namespace functions { -class ExecScriptScopedAllowBaseSyncPrimitives; -} namespace gl { struct GLImplementationParts; namespace init { @@ -438,10 +433,6 @@ class WebMainLoop; } // namespace web -namespace webrtc { -class DesktopConfigurationMonitor; -} - namespace base { class Environment; } @@ -767,7 +758,6 @@ friend class content::ServiceWorkerContextClient; friend class device::UsbContext; friend class enterprise_connectors::LinuxKeyRotationCommand; - friend class functions::ExecScriptScopedAllowBaseSyncPrimitives; friend class history_report::HistoryReportJniBridge; friend class internal::TaskTracker; friend class leveldb::port::CondVar; @@ -785,7 +775,6 @@ friend class syncer::HttpBridge; friend class syncer::GetLocalChangesRequest; friend class updater::SystemctlLauncherScopedAllowBaseSyncPrimitives; - friend class webrtc::DesktopConfigurationMonitor; // Usage that should be fixed: // Sorted by class name (with namespace). @@ -837,7 +826,6 @@ friend class base::StackSamplingProfiler; friend class base::internal::JobTaskSource; friend class base::sequence_manager::internal::TaskQueueImpl; - friend class blink::LegacyWebRtcVideoFrameAdapter; friend class blink::RTCVideoDecoderAdapter; friend class blink::RTCVideoEncoder; friend class blink::WebRtcVideoFrameAdapter; @@ -849,7 +837,6 @@ friend class content::EmergencyTraceFinalisationCoordinator; friend class content::InProcessUtilityThread; friend class content::RenderProcessHost; - friend class content::RTCVideoDecoder; friend class content::SandboxHostLinux; friend class content::ScopedAllowWaitForDebugURL; friend class content::SynchronousCompositor;
diff --git a/base/win/scoped_winrt_initializer.cc b/base/win/scoped_winrt_initializer.cc index 85f83dab..4c93dcfa 100644 --- a/base/win/scoped_winrt_initializer.cc +++ b/base/win/scoped_winrt_initializer.cc
@@ -5,61 +5,14 @@ #include "base/win/scoped_winrt_initializer.h" #include <roapi.h> -#include <windows.h> - -#include <ostream> #include "base/check_op.h" -#include "base/threading/scoped_thread_priority.h" #include "base/win/com_init_util.h" -#include "base/win/core_winrt_util.h" namespace base::win { -namespace { - -FARPROC LoadComBaseFunction(const char* function_name) { - static HMODULE const handle = []() { - // Mitigate the issues caused by loading DLLs on a background thread - // (http://crbug/973868). - SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY(); - return ::LoadLibraryEx(L"combase.dll", nullptr, - LOAD_LIBRARY_SEARCH_SYSTEM32); - }(); - return handle ? ::GetProcAddress(handle, function_name) : nullptr; -} - -decltype(&::RoInitialize) GetRoInitializeFunction() { - static decltype(&::RoInitialize) const function = - reinterpret_cast<decltype(&::RoInitialize)>( - LoadComBaseFunction("RoInitialize")); - return function; -} - -decltype(&::RoUninitialize) GetRoUninitializeFunction() { - static decltype(&::RoUninitialize) const function = - reinterpret_cast<decltype(&::RoUninitialize)>( - LoadComBaseFunction("RoUninitialize")); - return function; -} - -HRESULT CallRoInitialize(RO_INIT_TYPE init_type) { - auto ro_initialize_func = GetRoInitializeFunction(); - if (!ro_initialize_func) - return E_FAIL; - return ro_initialize_func(init_type); -} - -void CallRoUninitialize() { - auto ro_uninitialize_func = GetRoUninitializeFunction(); - if (ro_uninitialize_func) - ro_uninitialize_func(); -} - -} // namespace - ScopedWinrtInitializer::ScopedWinrtInitializer() - : hr_(CallRoInitialize(RO_INIT_MULTITHREADED)) { + : hr_(::RoInitialize(RO_INIT_MULTITHREADED)) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); #if DCHECK_IS_ON() if (SUCCEEDED(hr_)) @@ -72,7 +25,7 @@ ScopedWinrtInitializer::~ScopedWinrtInitializer() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (SUCCEEDED(hr_)) - CallRoUninitialize(); + ::RoUninitialize(); } bool ScopedWinrtInitializer::Succeeded() const {
diff --git a/build/fuchsia/update_product_bundles.py b/build/fuchsia/update_product_bundles.py index 7202b6a..0cd024a1 100755 --- a/build/fuchsia/update_product_bundles.py +++ b/build/fuchsia/update_product_bundles.py
@@ -95,76 +95,6 @@ return repos -def remove_product_bundle(product_bundle): - """Removes product-bundle given.""" - common.run_ffx_command(cmd=('product-bundle', 'remove', '-f', product_bundle)) - - -def get_product_bundle_urls(): - """Retrieves URLs of available product-bundles. - - Returns: - List of dictionaries of structure, indicating whether the product-bundle - has been downloaded. - { - 'url': <GCS path of product-bundle>, - 'downloaded': <True|False> - } - """ - # TODO(fxb/115328): Replaces with JSON API when available. - bundles = common.run_ffx_command(cmd=('product-bundle', 'list'), - capture_output=True).stdout.strip() - urls = [ - line.strip() for line in bundles.splitlines() if 'gs://fuchsia' in line - ] - structured_urls = [] - for url in urls: - downloaded = False - if '*' in url: - downloaded = True - url = url.split(' ')[1] - structured_urls.append({'downloaded': downloaded, 'url': url.strip()}) - return structured_urls - - -def get_product_bundles(): - """Lists all downloaded product-bundles for the given SDK. - - Cross-references the repositories with downloaded packages and the stated - downloaded product-bundles to validate whether or not a product-bundle is - present. Prunes invalid product-bundles with each call as well. - - Returns: - List of strings of product-bundle names downloaded and that FFX is aware - of. - """ - downloaded_bundles = [] - - for url in get_product_bundle_urls(): - if url['downloaded']: - # The product is separated by a # - product = url['url'].split('#') - downloaded_bundles.append(product[1]) - - repos = get_repositories() - - # Some repo names do not match product-bundle names due to underscores. - # Normalize them both. - repo_names = set([repo['name'].replace('-', '_') for repo in repos]) - - def bundle_is_active(name): - # Returns True if the product-bundle named `name` is present in a package - # repository (assuming it is downloaded already); otherwise, removes the - # product-bundle and returns False. - if name.replace('-', '_') in repo_names: - return True - - remove_product_bundle(name) - return False - - return list(filter(bundle_is_active, downloaded_bundles)) - - def get_current_signature(image_dir): """Determines the current version of the image, if it exists. @@ -203,11 +133,6 @@ logging.debug('Getting new SDK hash') new_sdk_hash = common.get_hash_from_sdk() - # Remove any product bundles that remain. - legacy_bundles = get_product_bundles() - for bundle in legacy_bundles: - remove_product_bundle(bundle) - for product in new_products: prod, board = product.split('.', 1) image_dir = os.path.join(common.IMAGES_ROOT, prod, board)
diff --git a/build/fuchsia/update_product_bundles_test.py b/build/fuchsia/update_product_bundles_test.py index 7d7c5a6..5cb7cbe6 100755 --- a/build/fuchsia/update_product_bundles_test.py +++ b/build/fuchsia/update_product_bundles_test.py
@@ -10,8 +10,6 @@ import unittest from unittest import mock -from parameterized import parameterized - import update_product_bundles sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), @@ -99,97 +97,6 @@ check=True) ]) - def testRemoveProductBundle(self): - update_product_bundles.remove_product_bundle('some-bundle-foo-bar') - - self._ffx_mock.assert_called_once_with(cmd=('product-bundle', 'remove', - '-f', 'some-bundle-foo-bar')) - - def _InitFFXRunWithProductBundleList(self, sdk_version='10.20221114.2.1'): - self._ffx_mock.return_value.stdout = f""" - gs://fuchsia/{sdk_version}/bundles.json#workstation_eng.qemu-x64 - gs://fuchsia/{sdk_version}/bundles.json#workstation_eng.chromebook-x64-dfv2 -* gs://fuchsia/{sdk_version}/bundles.json#workstation_eng.chromebook-x64 -* gs://fuchsia/{sdk_version}/bundles.json#terminal.qemu-x64 - gs://fuchsia/{sdk_version}/bundles.json#terminal.qemu-arm64 -* gs://fuchsia/{sdk_version}/bundles.json#core.x64-dfv2 - -*No need to fetch with `ffx product-bundle get ...`. - """ - - def testGetProductBundleUrlsMarksDesiredAsDownloaded(self): - self._InitFFXRunWithProductBundleList() - urls = update_product_bundles.get_product_bundle_urls() - expected_urls = [{ - 'url': - 'gs://fuchsia/10.20221114.2.1/bundles.json#workstation_eng.qemu-x64', - 'downloaded': False, - }, { - 'url': ('gs://fuchsia/10.20221114.2.1/bundles.json#workstation_eng.' - 'chromebook-x64-dfv2'), - 'downloaded': - False, - }, { - 'url': ('gs://fuchsia/10.20221114.2.1/bundles.json#workstation_eng.' - 'chromebook-x64'), - 'downloaded': - True, - }, { - 'url': 'gs://fuchsia/10.20221114.2.1/bundles.json#terminal.qemu-x64', - 'downloaded': True, - }, { - 'url': 'gs://fuchsia/10.20221114.2.1/bundles.json#terminal.qemu-arm64', - 'downloaded': False, - }, { - 'url': 'gs://fuchsia/10.20221114.2.1/bundles.json#core.x64-dfv2', - 'downloaded': True, - }] - - for i, url in enumerate(urls): - self.assertEqual(url, expected_urls[i]) - - @mock.patch('update_product_bundles.get_repositories') - def testGetProductBundlesExtractsProductBundlesFromURLs(self, mock_get_repos): - self._InitFFXRunWithProductBundleList() - mock_get_repos.return_value = [{ - 'name': 'workstation-eng.chromebook-x64' - }, { - 'name': 'terminal.qemu-x64' - }, { - 'name': 'core.x64-dfv2' - }] - - self.assertEqual( - set(update_product_bundles.get_product_bundles()), - set([ - 'workstation_eng.chromebook-x64', - 'terminal.qemu-x64', - 'core.x64-dfv2', - ])) - - @mock.patch('update_product_bundles.get_repositories') - def testGetProductBundlesExtractsProductBundlesFromURLsFiltersMissingRepos( - self, mock_get_repos): - self._InitFFXRunWithProductBundleList() - - # This will be missing two repos from the bundle list: - # core and terminal.qemu-x64 - # Additionally, workstation-eng != workstation_eng, but they will be treated - # as the same product-bundle - mock_get_repos.return_value = [{ - 'name': 'workstation-eng.chromebook-x64' - }, { - 'name': 'terminal.qemu-arm64' - }] - - self.assertEqual(update_product_bundles.get_product_bundles(), - ['workstation_eng.chromebook-x64']) - self._ffx_mock.assert_has_calls([ - mock.call(cmd=('product-bundle', 'remove', '-f', 'terminal.qemu-x64')), - mock.call(cmd=('product-bundle', 'remove', '-f', 'core.x64-dfv2')), - ], - any_order=True) - if __name__ == '__main__': unittest.main()
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 7c0956d..5a1bb18 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -261,6 +261,7 @@ "//chrome/browser/readaloud/android:hooks_public_impl_java", "//chrome/browser/supervised_user:parent_auth_delegate_impl_java", "//chrome/browser/touch_to_fill/android/internal:resource_provider_public_impl_java", + "//chrome/browser/ui/android/cars:delegate_public_impl_java", "//chrome/browser/ui/android/hats/internal:provider_public_impl_java", "//chrome/browser/xsurface_provider:hooks_public_impl_java", "//components/environment_integrity/android:integrity_service_bridge_public_impl_java", @@ -417,6 +418,7 @@ "//chrome/browser/ui/android/favicon:java", "//chrome/browser/ui/android/hats:factory_java", "//chrome/browser/ui/android/hats:java", + "//chrome/browser/ui/android/hats/internal:controller_java", "//chrome/browser/ui/android/layouts:java", "//chrome/browser/ui/android/layouts/glue:java", "//chrome/browser/ui/android/logo:java", @@ -1033,6 +1035,7 @@ "//chrome/browser/ui/android/edge_to_edge/internal:junit", "//chrome/browser/ui/android/fast_checkout/internal:junit", "//chrome/browser/ui/android/favicon:java", + "//chrome/browser/ui/android/hats/internal:controller_java", "//chrome/browser/ui/android/hats/internal:junit", "//chrome/browser/ui/android/layouts:java", "//chrome/browser/ui/android/layouts:junit", @@ -1629,6 +1632,7 @@ "//chrome/browser/ui/android/device_lock:java_resources", "//chrome/browser/ui/android/device_lock:javatests", "//chrome/browser/ui/android/favicon:java", + "//chrome/browser/ui/android/hats/internal:controller_java", "//chrome/browser/ui/android/layouts:java", "//chrome/browser/ui/android/layouts/test:java", "//chrome/browser/ui/android/logo:java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java index 33483b9b..51b9af62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -113,7 +113,7 @@ * @return The created {@link SurveyController}. */ public SurveyController createSurveyController() { - return new SurveyController(); + return null; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java index cf32070..80aef5f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java
@@ -50,7 +50,6 @@ private List<BookmarkId> mBookmarkIds; private BookmarkImageFetcher mBookmarkImageFetcher; private BookmarkFolderPickerCoordinator mCoordinator; - private BookmarkId mInitialParentId; @Override protected void onCreate(Bundle savedInstanceState) { @@ -81,12 +80,11 @@ mBookmarkModel); BookmarkUiPrefs bookmarkUiPrefs = new BookmarkUiPrefs(SharedPreferencesManager.getInstance()); - mInitialParentId = mBookmarkModel.getBookmarkById(mBookmarkIds.get(0)).getParentId(); // TODO(crbug.com/1472832): Consider initializing this in #onCreateOptionsMenu to avoid the // possibility that the menu is null when the first parent is set. mCoordinator = new BookmarkFolderPickerCoordinator(this, mBookmarkModel, - mBookmarkImageFetcher, mBookmarkIds, mInitialParentId, this::finish, - addNewFolderCoordinator, bookmarkUiPrefs, + mBookmarkImageFetcher, mBookmarkIds, this::finish, addNewFolderCoordinator, + bookmarkUiPrefs, new ImprovedBookmarkRowCoordinator(this, mBookmarkImageFetcher, mBookmarkModel, bookmarkUiPrefs, ShoppingServiceFactory.getForProfile(profile)));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java index 895fb0c..18b310bc9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerCoordinator.java
@@ -55,8 +55,7 @@ public BookmarkFolderPickerCoordinator(Context context, BookmarkModel bookmarkModel, BookmarkImageFetcher bookmarkImageFetcher, List<BookmarkId> bookmarkIds, - BookmarkId initialParentId, Runnable finishRunnable, - BookmarkAddNewFolderCoordinator addNewFolderCoordinator, + Runnable finishRunnable, BookmarkAddNewFolderCoordinator addNewFolderCoordinator, BookmarkUiPrefs bookmarkUiPrefs, ImprovedBookmarkRowCoordinator improvedBookmarkRowCoordinator) { mContext = context; @@ -74,7 +73,7 @@ PropertyModelChangeProcessor.create(model, mView, BookmarkFolderPickerViewBinder::bind); mMediator = new BookmarkFolderPickerMediator(context, bookmarkModel, bookmarkImageFetcher, - bookmarkIds, initialParentId, finishRunnable, + bookmarkIds, finishRunnable, new BookmarkUiPrefs(SharedPreferencesManager.getInstance()), model, mModelList, addNewFolderCoordinator, improvedBookmarkRowCoordinator);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java index a4a3bb1..686fe22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediator.java
@@ -18,6 +18,7 @@ import org.chromium.ui.modelutil.PropertyModel; import java.util.List; +import java.util.Objects; /** Mediator for the folder picker activity. */ class BookmarkFolderPickerMediator { @@ -56,6 +57,7 @@ private final BookmarkAddNewFolderCoordinator mAddNewFolderCoordinator; private final ImprovedBookmarkRowCoordinator mImprovedBookmarkRowCoordinator; private final BookmarkUiPrefs mBookmarkUiPrefs; + private final boolean mAllMovedBookmarksMatchParent; private boolean mMovingAtLeastOneFolder; private boolean mMovingAtLeastOneBookmark; @@ -64,9 +66,8 @@ BookmarkFolderPickerMediator(Context context, BookmarkModel bookmarkModel, BookmarkImageFetcher bookmarkImageFetcher, List<BookmarkId> bookmarkIds, - BookmarkId initialParentId, Runnable finishRunnable, BookmarkUiPrefs bookmarkUiPrefs, - PropertyModel model, ModelList modelList, - BookmarkAddNewFolderCoordinator addNewFolderCoordinator, + Runnable finishRunnable, BookmarkUiPrefs bookmarkUiPrefs, PropertyModel model, + ModelList modelList, BookmarkAddNewFolderCoordinator addNewFolderCoordinator, ImprovedBookmarkRowCoordinator improvedBookmarkRowCoordinator) { mContext = context; mBookmarkModel = bookmarkModel; @@ -79,10 +80,11 @@ mModelList = modelList; mAddNewFolderCoordinator = addNewFolderCoordinator; mImprovedBookmarkRowCoordinator = improvedBookmarkRowCoordinator; - mInitialParentId = initialParentId; mBookmarkUiPrefs = bookmarkUiPrefs; mBookmarkUiPrefs.addObserver(mBookmarkUiPrefsObserver); + boolean allMovedBookmarksMatchParent = true; + BookmarkId firstParent = mBookmarkModel.getBookmarkById(mBookmarkIds.get(0)).getParentId(); for (BookmarkId id : mBookmarkIds) { BookmarkItem item = mBookmarkModel.getBookmarkById(id); if (item.isFolder()) { @@ -90,7 +92,17 @@ } else { mMovingAtLeastOneBookmark = true; } + + // If all of the bookmarks being moved have the same parent, then that's used for the + // initial parent. + if (!Objects.equals(firstParent, item.getParentId())) { + allMovedBookmarksMatchParent = false; + } } + mAllMovedBookmarksMatchParent = allMovedBookmarksMatchParent; + // TODO(crbug.com/1473755): Implement lowest common ancestor here for the initial parent. + mInitialParentId = + mAllMovedBookmarksMatchParent ? firstParent : mBookmarkModel.getRootFolderId(); mModel.set(BookmarkFolderPickerProperties.CANCEL_CLICK_LISTENER, this::onCancelClicked); mModel.set(BookmarkFolderPickerProperties.MOVE_CLICK_LISTENER, this::onMoveClicked); @@ -166,8 +178,18 @@ } void updateButtonsForCurrentParent() { + BookmarkId currentParentId = mCurrentParentItem.getId(); + // Folders are removed from the list in {@link #populateFoldersForParentId}, but it's still + // possible to get to invalid folders through hierarchy navigation (e.g. the root folder + // by navigating up all the way). + boolean isInvalidFolderLocation = (mMovingAtLeastOneFolder + && !BookmarkUtils.canAddFolderToParent(mBookmarkModel, currentParentId)); + boolean isInvalidBookmarkLocation = (mMovingAtLeastOneBookmark + && !BookmarkUtils.canAddBookmarkToParent(mBookmarkModel, currentParentId)); + boolean isInitialParent = + mAllMovedBookmarksMatchParent && Objects.equals(currentParentId, mInitialParentId); mModel.set(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED, - mBookmarkIds.size() > 1 || !mCurrentParentItem.getId().equals(mInitialParentId)); + !isInvalidFolderLocation && !isInvalidBookmarkLocation && !isInitialParent); updateToolbarButtons(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java index 28675eb..94602dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java
@@ -15,7 +15,6 @@ import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; import org.chromium.chrome.browser.ChromeActivitySessionTracker; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.components.variations.firstrun.VariationsSeedFetcher; import org.chromium.components.version_info.VersionInfo; import org.chromium.content_public.browser.ChildProcessLauncherHelper; @@ -167,9 +166,6 @@ --mNumPendingSuccesses; if (mNumPendingSuccesses == 0) { // All tasks succeeded: Finish tasks, call onSuccess(), and reach terminal state. - if (CachedFeatureFlags.isNetworkServiceWarmUpEnabled()) { - ChildProcessLauncherHelper.warmUp(ContextUtils.getApplicationContext(), false); - } if (mAllocateChildConnection) { ChildProcessLauncherHelper.warmUp(ContextUtils.getApplicationContext(), true); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java index 7343364..f056c248 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -35,6 +35,8 @@ import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; +import org.chromium.chrome.browser.ui.hats.SurveyController; +import org.chromium.chrome.browser.ui.hats.SurveyControllerProvider; import org.chromium.components.messages.DismissReason; import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; @@ -63,6 +65,8 @@ static final String MAX_NUMBER = "max-number"; @VisibleForTesting static final String SITE_ID_PARAM_NAME = "site-id"; + + private static @Nullable SurveyController sControllerForTesting; private static boolean sForceUmaEnabledForTesting; private static boolean sMessageShown; @@ -147,7 +151,8 @@ mLoggingHandler = new Handler(); mTabModelSelector = tabModelSelector; - mSurveyController = SurveyController.create(); + mSurveyController = sControllerForTesting != null ? sControllerForTesting + : SurveyControllerProvider.create(); Runnable onSuccessRunnable = () -> onSurveyAvailable(mTriggerId); Runnable onFailureRunnable = () -> Log.w(TAG, "Survey does not exists or download failed."); mSurveyController.downloadSurvey(context, mTriggerId, onSuccessRunnable, onFailureRunnable); @@ -285,7 +290,7 @@ */ private void showSurvey(String siteId) { mSurveyController.showSurveyIfAvailable( - mActivity, siteId, true, R.drawable.chrome_sync_logo, mLifecycleDispatcher); + mActivity, siteId, R.drawable.chrome_sync_logo, mLifecycleDispatcher, null); } /** @@ -501,4 +506,12 @@ public static void resetMessageShownForTesting() { sMessageShown = false; } + + /** + * Set the test only survey controller to use instead of creating new SurveyController. + */ + public static void setSurveyControllerForTesting(SurveyController surveyController) { + sControllerForTesting = surveyController; + ResettersForTesting.register(() -> sControllerForTesting = null); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyController.java index 62e3387..5b47b14 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyController.java
@@ -10,7 +10,6 @@ import androidx.annotation.Nullable; import org.chromium.base.ResettersForTesting; -import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import java.util.Map; @@ -30,7 +29,7 @@ if (sTestInstance != null) { return sTestInstance; } - return AppHooks.get().createSurveyController(); + return new SurveyController(); } /** Set the instance to use for survey related tests. Reset back to null after tests. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index f45263f..429d327 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -22,6 +22,7 @@ import android.view.ViewStub; import android.widget.FrameLayout; +import androidx.activity.BackEventCompat; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -67,6 +68,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.fullscreen.FullscreenOptions; +import org.chromium.chrome.browser.gesturenav.TabOnBackGestureHandler; import org.chromium.chrome.browser.history.HistoryManagerUtils; import org.chromium.chrome.browser.homepage.HomepageManager; import org.chromium.chrome.browser.homepage.HomepagePolicyManager; @@ -157,6 +159,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; +import org.chromium.components.browser_ui.widget.gesture.BackPressHandler.BackPressResult; import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams; import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; @@ -174,6 +177,7 @@ import org.chromium.content_public.browser.NavigationHandle; import org.chromium.content_public.browser.WebContents; import org.chromium.net.NetError; +import org.chromium.ui.base.BackGestureEventSwipeEdge; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; import org.chromium.ui.base.WindowAndroid; @@ -190,7 +194,7 @@ */ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserver, TintObserver, MenuButtonDelegate, ChromeAccessibilityUtil.Observer, - TabObscuringHandler.Observer, BackPressHandler { + TabObscuringHandler.Observer { private final IncognitoStateProvider mIncognitoStateProvider; private final TabCountProvider mTabCountProvider; private final TopUiThemeColorProvider mTopUiThemeColorProvider; @@ -383,6 +387,48 @@ } } + private class OnBackPressHandler implements BackPressHandler { + private TabOnBackGestureHandler mHandler; + + @Override + public int handleBackPress() { + int res = ToolbarManager.this.handleBackPress(); + // For U+ only. + if (mHandler != null) mHandler.onBackInvoked(); + return res; + } + + @Override + public ObservableSupplier<Boolean> getHandleBackPressChangedSupplier() { + return ToolbarManager.this.mBackPressStateSupplier; + } + + @Override + public void handleOnBackCancelled() { + mHandler.onBackCancelled(); + } + + @Override + public void handleOnBackProgressed(@NonNull BackEventCompat backEvent) { + mHandler.onBackProgressed(backEvent.getTouchX(), backEvent.getTouchY(), + backEvent.getProgress(), + backEvent.getSwipeEdge() == BackEventCompat.EDGE_LEFT + ? BackGestureEventSwipeEdge.LEFT + : BackGestureEventSwipeEdge.RIGHT); + } + + @Override + public void handleOnBackStarted(@NonNull BackEventCompat backEvent) { + mHandler = TabOnBackGestureHandler.from(mActivityTabProvider.get()); + mHandler.onBackStarted(backEvent.getTouchX(), backEvent.getTouchY(), + backEvent.getProgress(), + backEvent.getSwipeEdge() == BackEventCompat.EDGE_LEFT + ? BackGestureEventSwipeEdge.LEFT + : BackGestureEventSwipeEdge.RIGHT, + false); + } + } + /** * Creates a ToolbarManager object. * @@ -566,7 +612,8 @@ this::updateButtonStatus, mActivityTabProvider); // clang-format on if (backPressManager != null && BackPressManager.isEnabled()) { - backPressManager.addHandler(this, BackPressHandler.Type.TAB_HISTORY); + OnBackPressHandler handler = new OnBackPressHandler(); + backPressManager.addHandler(handler, BackPressHandler.Type.TAB_HISTORY); mLastBackPressMsSupplier = backPressManager::getLastPressMs; } @@ -2204,7 +2251,6 @@ mBackPressStateSupplier.set(tab != null && mToolbarTabController.canGoBack()); } - @Override public @BackPressResult int handleBackPress() { boolean ret = back(); if (!ret) { @@ -2231,7 +2277,6 @@ return ret ? BackPressResult.SUCCESS : BackPressResult.FAILURE; } - @Override public ObservableSupplier<Boolean> getHandleBackPressChangedSupplier() { return mBackPressStateSupplier; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java index 4f718f8..fa7c337 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.components.browser_ui.widget.TintedDrawable; import org.chromium.device.mojom.ScreenOrientationLockType; +import org.chromium.ui.util.ColorUtils; /** * Stores info about a web app. @@ -104,6 +105,15 @@ @Override public @NonNull ColorProvider getColorProvider() { + boolean inDarkMode = ColorUtils.inNightMode(ContextUtils.getApplicationContext()); + boolean hasValidDarkToolbar = mDarkColorProvider.hasCustomToolbarColor(); + boolean hasValidLightToolbar = mColorProvider.hasCustomToolbarColor(); + return inDarkMode && (hasValidDarkToolbar || !hasValidLightToolbar) ? mDarkColorProvider + : mColorProvider; + } + + @Override + public @NonNull ColorProvider getLightColorProvider() { return mColorProvider; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerRenderTest.java index d857ca5..43019fd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerRenderTest.java
@@ -242,9 +242,8 @@ mBookmarkUiPrefs, mShoppingService); mCoordinator = new BookmarkFolderPickerCoordinator(mActivity, mBookmarkModel, - mBookmarkImageFetcher, Arrays.asList(mUserBookmarkId), mUserFolderId, - mFinishRunnable, mAddNewFolderCoordinator, mBookmarkUiPrefs, - mImprovedBookmarkRowCoordinator); + mBookmarkImageFetcher, Arrays.asList(mUserBookmarkId), mFinishRunnable, + mAddNewFolderCoordinator, mBookmarkUiPrefs, mImprovedBookmarkRowCoordinator); mContentView.addView(mCoordinator.getView()); Toolbar toolbar = (Toolbar) mContentView.findViewById(R.id.toolbar);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java index b69de30..16a57a8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.ui.hats.SurveyController; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; @@ -42,6 +43,7 @@ import org.chromium.ui.test.util.UiRestriction; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -82,7 +84,7 @@ mSharedPreferenceManager = SharedPreferencesManager.getInstance(); mTestSurveyController = new AlwaysSuccessfulSurveyController(); - SurveyController.setInstanceForTesting(mTestSurveyController); + ChromeSurveyController.setSurveyControllerForTesting(mTestSurveyController); mActivityTestRule.startMainActivityOnBlankPage(); @@ -167,7 +169,7 @@ return messages.size() == 0 ? null : MessagesTestHelper.getCurrentMessage(messages.get(0)); } - private static class AlwaysSuccessfulSurveyController extends SurveyController { + private static class AlwaysSuccessfulSurveyController implements SurveyController { public final CallbackHelper downloadCallbackHelper = new CallbackHelper(); public final CallbackHelper showSurveyCallbackHelper = new CallbackHelper(); @@ -181,9 +183,8 @@ } @Override - public void showSurveyIfAvailable(Activity activity, String siteId, - boolean showAsBottomSheet, int displayLogoResId, - ActivityLifecycleDispatcher lifecycleDispatcher) { + public void showSurveyIfAvailable(Activity activity, String siteId, int displayLogoResId, + ActivityLifecycleDispatcher lifecycleDispatcher, Map<String, String> surveyPsd) { showSurveyCallbackHelper.notifyCalled(); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java index 5bf65b1..a63b029b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java
@@ -81,6 +81,10 @@ private final BookmarkId mUserBookmarkId = new BookmarkId(/*id=*/7, BookmarkType.NORMAL); private final BookmarkId mUserFolderId2 = new BookmarkId(/*id=*/8, BookmarkType.NORMAL); private final BookmarkId mUserBookmarkId1 = new BookmarkId(/*id=*/9, BookmarkType.NORMAL); + private final BookmarkId mReadingListItemId1 = + new BookmarkId(/*id=*/10, BookmarkType.READING_LIST); + private final BookmarkId mReadingListItemId2 = + new BookmarkId(/*id=*/11, BookmarkType.READING_LIST); private final BookmarkItem mRootFolderItem = new BookmarkItem(mRootFolderId, "Root", null, true, null, false, false, 0, false, 0); @@ -102,6 +106,10 @@ private final BookmarkItem mUserBookmarkItem1 = new BookmarkItem(mUserBookmarkId1, "Bookmark1", JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), false, mUserFolderId, true, false, 0, false, 0); + private final BookmarkItem mReadingListItem1 = new BookmarkItem(mReadingListItemId1, + "Reading list item 1", null, true, mReadingListFolderId, false, false, 0, false, 0); + private final BookmarkItem mReadingListItem2 = new BookmarkItem(mReadingListItemId2, + "Reading list item 2", null, true, mReadingListFolderId, false, false, 0, false, 0); @Mock private BookmarkImageFetcher mBookmarkImageFetcher; @@ -176,6 +184,9 @@ doReturn(Arrays.asList()).when(mBookmarkModel).getChildIds(mUserFolderId2); doReturn(0).when(mBookmarkModel).getTotalBookmarkCount(mUserFolderId2); doReturn(mUserBookmarkItem).when(mBookmarkModel).getBookmarkById(mUserBookmarkId); + doReturn(mUserBookmarkItem1).when(mBookmarkModel).getBookmarkById(mUserBookmarkId1); + doReturn(mReadingListItem1).when(mBookmarkModel).getBookmarkById(mReadingListItemId1); + doReturn(mReadingListItem2).when(mBookmarkModel).getBookmarkById(mReadingListItemId2); doReturn(true).when(mBookmarkModel).doesBookmarkExist(any()); doAnswer((invocation) -> { Runnable runnable = invocation.getArgument(0); @@ -200,8 +211,8 @@ .fetchFirstTwoImagesForFolder(any(), any()); mMediator = new BookmarkFolderPickerMediator(mActivity, mBookmarkModel, - mBookmarkImageFetcher, Arrays.asList(mUserBookmarkId), mUserFolderId, - mFinishRunnable, mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, + mBookmarkImageFetcher, Arrays.asList(mUserBookmarkId), mFinishRunnable, + mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, new ImprovedBookmarkRowCoordinator(mActivity, mBookmarkImageFetcher, mBookmarkModel, mBookmarkUiPrefs, mShoppingService)); } @@ -209,7 +220,7 @@ @Test public void testMoveFolder() { mMediator = new BookmarkFolderPickerMediator(mActivity, mBookmarkModel, - mBookmarkImageFetcher, Arrays.asList(mUserFolderId), mUserFolderId, mFinishRunnable, + mBookmarkImageFetcher, Arrays.asList(mUserFolderId), mFinishRunnable, mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, new ImprovedBookmarkRowCoordinator(mActivity, mBookmarkImageFetcher, mBookmarkModel, mBookmarkUiPrefs, mShoppingService)); @@ -258,7 +269,7 @@ mMediator.populateFoldersForParentId(mRootFolderId); assertEquals(4, mModelList.size()); assertEquals("Move to…", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); - assertTrue(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); + assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); } @Test @@ -291,4 +302,40 @@ BookmarkRowDisplayPref.VISUAL); assertEquals(2, mModelList.size()); } + + @Test + public void testMoveMultiple_sharedParent() { + mMediator = new BookmarkFolderPickerMediator(mActivity, mBookmarkModel, + mBookmarkImageFetcher, Arrays.asList(mUserBookmarkId, mUserBookmarkId1), + mFinishRunnable, mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, + new ImprovedBookmarkRowCoordinator(mActivity, mBookmarkImageFetcher, mBookmarkModel, + mBookmarkUiPrefs, mShoppingService)); + + assertEquals("UserFolder", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); + assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); + } + + @Test + public void testMoveMultiple_noSharedParent() { + mMediator = new BookmarkFolderPickerMediator(mActivity, mBookmarkModel, + mBookmarkImageFetcher, Arrays.asList(mUserFolderId, mUserBookmarkId1), + mFinishRunnable, mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, + new ImprovedBookmarkRowCoordinator(mActivity, mBookmarkImageFetcher, mBookmarkModel, + mBookmarkUiPrefs, mShoppingService)); + + assertEquals("Move to…", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); + assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); + } + + @Test + public void testMoveMultiple_readingList() { + mMediator = new BookmarkFolderPickerMediator(mActivity, mBookmarkModel, + mBookmarkImageFetcher, Arrays.asList(mReadingListItemId1, mReadingListItemId2), + mFinishRunnable, mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, + new ImprovedBookmarkRowCoordinator(mActivity, mBookmarkImageFetcher, mBookmarkModel, + mBookmarkUiPrefs, mShoppingService)); + + assertEquals("Reading List", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); + assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java index 17045b9..09e21e8f4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java
@@ -55,6 +55,7 @@ import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; +import org.chromium.chrome.browser.ui.hats.SurveyController; import org.chromium.components.messages.DismissReason; import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; @@ -123,7 +124,7 @@ mFieldTrialParams.put(ChromeSurveyController.MAX_NUMBER, "1"); enableChromeSurveyNextFeatureWithParams(mFieldTrialParams, true); - SurveyController.setInstanceForTesting(mTestSurveyController); + ChromeSurveyController.setSurveyControllerForTesting(mTestSurveyController); ChromeSurveyController.forceIsUMAEnabledForTesting(true); mPrefKeyPromptShown = @@ -634,7 +635,7 @@ FeatureList.setTestValues(testValues); } - private static class TestSurveyController extends SurveyController { + private static class TestSurveyController implements SurveyController { public final CallbackHelper downloadIfApplicableCallback = new CallbackHelper(); public final CallbackHelper showSurveyIfAvailableCallback = new CallbackHelper(); public boolean isSurveyExpired; @@ -654,9 +655,9 @@ } @Override - public void showSurveyIfAvailable(Activity activity, String siteId, - boolean showAsBottomSheet, int displayLogoResId, - @Nullable ActivityLifecycleDispatcher lifecycleDispatcher) { + public void showSurveyIfAvailable(Activity activity, String triggerId, int displayLogoResId, + @Nullable ActivityLifecycleDispatcher lifecycleDispatcher, + @Nullable Map<String, String> psd) { showSurveyIfAvailableCallback.notifyCalled(); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java index 639130e..7ce65de 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java
@@ -14,7 +14,6 @@ import androidx.annotation.NonNull; -import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -79,11 +78,6 @@ Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown()); } - @After - public void after() { - FirstRunStatus.setFirstRunTriggered(false); - } - @Test public void testPromptDisplayedBefore() { final String triggerId1 = "triggerId1"; @@ -226,7 +220,7 @@ @Test public void testEligibilityFirstRun() { - FirstRunStatus.setFirstRunTriggered(true); + FirstRunStatus.setFirstRunTriggeredForTesting(true); mRiggedThrottler = new RiggedSurveyThrottler(0, 1, 10); Assert.assertFalse( "Random selection should be false", mRiggedThrottler.isRandomlySelectedForSurvey());
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt index 8552764..bb7cd58 100644 --- a/chrome/android/profiles/arm.newest.txt +++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-117.0.5911.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-arm-118.0.5963.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index e9e06da8..d3643b8 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4873,8 +4873,6 @@ "metrics/structured/ash_structured_metrics_recorder.h", "metrics/structured/cros_events_processor.cc", "metrics/structured/cros_events_processor.h", - "metrics/structured/key_data_provider_ash.cc", - "metrics/structured/key_data_provider_ash.h", "metrics/structured/metadata_processor_ash.cc", "metrics/structured/metadata_processor_ash.h", "metrics/structured/structured_metrics_key_events_observer.cc", @@ -6260,15 +6258,12 @@ "enterprise/idle/action.h", "enterprise/idle/action_runner.cc", "enterprise/idle/action_runner.h", - "enterprise/idle/idle_features.cc", - "enterprise/idle/idle_features.h", "enterprise/idle/idle_service.cc", "enterprise/idle/idle_service.h", "enterprise/idle/idle_service_factory.cc", "enterprise/idle/idle_service_factory.h", - "enterprise/idle/idle_timeout_policy_handler.cc", - "enterprise/idle/idle_timeout_policy_handler.h", ] + deps += [ "//components/enterprise/idle" ] } if (is_linux || is_win || is_mac) {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 662c679..2ebd4f7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -10858,6 +10858,11 @@ flag_descriptions::kIndexedDBCompressValuesWithSnappyDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kIndexedDBCompressValuesWithSnappy)}, + {"autofill-enable-server-iban", + flag_descriptions::kAutofillEnableServerIbanName, + flag_descriptions::kAutofillEnableServerIbanDescription, kOsDesktop, + FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableServerIban)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc index f01cbd4..1da4f05 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc +++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
@@ -67,6 +67,17 @@ namespace accessibility_private = ::extensions::api::accessibility_private; using ::ash::AccessibilityManager; +ash::AccessibilityToastType ConvertToastType( + accessibility_private::ToastType type) { + switch (type) { + case accessibility_private::ToastType:: + TOAST_TYPE_DICTATIONNOFOCUSEDTEXTFIELD: + return ash::AccessibilityToastType::kDictationNoFocusedTextField; + case accessibility_private::ToastType::TOAST_TYPE_NONE: + NOTREACHED_NORETURN(); + } +} + ash::DictationBubbleHintType ConvertDictationHintType( accessibility_private::DictationBubbleHintType hint_type) { switch (hint_type) { @@ -782,6 +793,15 @@ return RespondNow(NoArguments()); } +ExtensionFunction::ResponseAction AccessibilityPrivateShowToastFunction::Run() { + absl::optional<accessibility_private::ShowToast::Params> params( + accessibility_private::ShowToast::Params::Create(args())); + EXTENSION_FUNCTION_VALIDATE(params); + ash::AccessibilityController::Get()->ShowToast( + ConvertToastType(params->type)); + return RespondNow(NoArguments()); +} + ExtensionFunction::ResponseAction AccessibilityPrivateShowConfirmationDialogFunction::Run() { absl::optional<accessibility_private::ShowConfirmationDialog::Params> params =
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.h b/chrome/browser/accessibility/accessibility_extension_api_chromeos.h index 39311db4..be96563 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.h +++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.h
@@ -240,6 +240,14 @@ ACCESSIBILITY_PRIVATE_SETVIRTUALKEYBOARDVISIBLE) }; +// API function that displays an accessibility-related toast. +class AccessibilityPrivateShowToastFunction : public ExtensionFunction { + ~AccessibilityPrivateShowToastFunction() override = default; + ResponseAction Run() override; + DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.showToast", + ACCESSIBILITY_PRIVATE_SHOWTOAST) +}; + // API function that shows a confirmation dialog, with callbacks for // confirm/cancel. class AccessibilityPrivateShowConfirmationDialogFunction
diff --git a/chrome/browser/accessibility/live_translate_controller_factory.cc b/chrome/browser/accessibility/live_translate_controller_factory.cc index b50cb89..305cb302 100644 --- a/chrome/browser/accessibility/live_translate_controller_factory.cc +++ b/chrome/browser/accessibility/live_translate_controller_factory.cc
@@ -49,9 +49,10 @@ return true; } -KeyedService* LiveTranslateControllerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +LiveTranslateControllerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* browser_context) const { - return new LiveTranslateController( + return std::make_unique<LiveTranslateController>( Profile::FromBrowserContext(browser_context)->GetPrefs(), browser_context); }
diff --git a/chrome/browser/accessibility/live_translate_controller_factory.h b/chrome/browser/accessibility/live_translate_controller_factory.h index 20ceb57..1872aae 100644 --- a/chrome/browser/accessibility/live_translate_controller_factory.h +++ b/chrome/browser/accessibility/live_translate_controller_factory.h
@@ -33,7 +33,7 @@ // BrowserContextKeyedServiceFactory: bool ServiceIsCreatedWithBrowserContext() const override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* browser_context) const override; };
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java index 3475ed6..0411445 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/BrowserServicesIntentDataProvider.java
@@ -251,8 +251,21 @@ return true; } + /** + * @return ColorProvider to be used. + */ public abstract @NonNull ColorProvider getColorProvider(); + /** + * @return ColorProvider when the system is in light mode. + */ + public @NonNull ColorProvider getLightColorProvider() { + return getColorProvider(); + } + + /** + * @return ColorProvider when the system is in dark mode. + */ public @NonNull ColorProvider getDarkColorProvider() { return getColorProvider(); }
diff --git a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java index 713dcd0..395ef9b 100644 --- a/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java +++ b/chrome/browser/android/browserservices/intents/java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfo.java
@@ -98,7 +98,7 @@ * ColorUtils.INVALID_COLOR otherwise. */ public long toolbarColor() { - return hasValidToolbarColor() ? mProvider.getColorProvider().getToolbarColor() + return hasValidToolbarColor() ? mProvider.getLightColorProvider().getToolbarColor() : ColorUtils.INVALID_COLOR; } @@ -106,7 +106,7 @@ * Returns whether the toolbar color specified in the Intent is valid. */ public boolean hasValidToolbarColor() { - return mProvider.getColorProvider().hasCustomToolbarColor(); + return mProvider.getLightColorProvider().hasCustomToolbarColor(); } /**
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc index 0d47626f0..f559b5a4 100644 --- a/chrome/browser/ash/accessibility/dictation_browsertest.cc +++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -8,6 +8,7 @@ #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/system_tray_test_api.h" +#include "ash/public/cpp/test/accessibility_controller_test_api.h" #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/system/accessibility/dictation_button_tray.h" @@ -316,6 +317,8 @@ utils_->set_wait_for_accessibility_common_extension_load_(use); } + DictationTestUtils* utils() { return utils_.get(); } + private: std::unique_ptr<DictationTestUtils> utils_; base::test::ScopedFeatureList scoped_feature_list_; @@ -2240,4 +2243,109 @@ SendFinalResultAndWaitForEditableValue("was one", "This was one test"); } +class AccessibilityToastCallbackManager { + public: + void OnToastShown() { run_loop_.Quit(); } + void WaitForToastShown() { run_loop_.Run(); } + + private: + base::RunLoop run_loop_; +}; + +class DictationKeyboardImprovementsTest : public DictationTestBase { + public: + DictationKeyboardImprovementsTest() = default; + ~DictationKeyboardImprovementsTest() override = default; + DictationKeyboardImprovementsTest(const DictationKeyboardImprovementsTest&) = + delete; + DictationKeyboardImprovementsTest& operator=( + const DictationKeyboardImprovementsTest&) = delete; + + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + DictationTestBase::SetUpCommandLine(command_line); + + std::vector<base::test::FeatureRef> enabled_features{ + ::features::kAccessibilityDictationKeyboardImprovements}; + scoped_feature_list_.InitWithFeatures( + enabled_features, std::vector<base::test::FeatureRef>()); + } + + void SetUpOnMainThread() override { + DictationTestBase::SetUpOnMainThread(); + test_api_ = AccessibilityControllerTestApi::Create(); + callback_manager_ = std::make_unique<AccessibilityToastCallbackManager>(); + test_api_->AddShowToastCallbackForTesting( + base::BindRepeating(&AccessibilityToastCallbackManager::OnToastShown, + base::Unretained(callback_manager_.get()))); + + // Tab away from the editable. + ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( + /*window=*/nullptr, /*key=*/ui::KeyboardCode::VKEY_TAB, + /*control=*/false, + /*shift=*/false, /*alt=*/false, /*command=*/false))); + // Reduce the no focused IME timeout so that the nudge will be shown + // promptly. + ExecuteAccessibilityCommonScript( + "testSupport.setNoFocusedImeTimeout(500);"); + } + + void WaitForToastShown() { callback_manager_->WaitForToastShown(); } + + private: + std::unique_ptr<AccessibilityControllerTestApi> test_api_; + std::unique_ptr<AccessibilityToastCallbackManager> callback_manager_; + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P( + NetworkDictationKeyboardImprovementsTest, + DictationKeyboardImprovementsTest, + ::testing::Values(TestConfig(speech::SpeechRecognitionType::kNetwork, + EditableType::kInput))); + +// Verifies that a nudge is shown in the system UI when Dictation is toggled +// when there is no focused editable. +IN_PROC_BROWSER_TEST_P(DictationKeyboardImprovementsTest, + ToggledWithNoFocusShowsNudge) { + // Disable the console observer because toggling Dictation in the following + // manner will cause an error to be emitted to the console. + utils()->DisableConsoleObserver(); + ToggleDictationWithKeystroke(); + WaitForToastShown(); + WaitForRecognitionStopped(); +} + +// Verifies that ChromeVox announces a message when when Dictation is toggled +// when there is no focused editable. +// TODO(b:259352600): Re-enable this test on MSAN. +#if defined(MEMORY_SANITIZER) +#define MAYBE_ToggledWithNoFocusTriggersSpeech \ + DISABLED_ToggledWithNoFocusTriggersSpeech +#else +#define MAYBE_ToggledWithNoFocusTriggersSpeech ToggledWithNoFocusTriggersSpeech +#endif +IN_PROC_BROWSER_TEST_P(DictationKeyboardImprovementsTest, + MAYBE_ToggledWithNoFocusTriggersSpeech) { + // Setup ChromeVox. + test::SpeechMonitor sm; + EXPECT_FALSE(GetManager()->IsSpokenFeedbackEnabled()); + extensions::ExtensionHostTestHelper host_helper( + browser()->profile(), extension_misc::kChromeVoxExtensionId); + EnableChromeVox(); + host_helper.WaitForHostCompletedFirstLoad(); + EXPECT_TRUE(GetManager()->IsSpokenFeedbackEnabled()); + + // Disable the console observer because toggling Dictation in the following + // manner will cause an error to be emitted to the console. + utils()->DisableConsoleObserver(); + ToggleDictationWithKeystroke(); + WaitForToastShown(); + WaitForRecognitionStopped(); + + // Assert speech from ChromeVox. + sm.ExpectSpeechPattern("*Go to a text field to use Dictation*"); + sm.Replay(); +} + } // namespace ash
diff --git a/chrome/browser/ash/accessibility/dictation_test_utils.cc b/chrome/browser/ash/accessibility/dictation_test_utils.cc index f27cf98..8c1e593 100644 --- a/chrome/browser/ash/accessibility/dictation_test_utils.cc +++ b/chrome/browser/ash/accessibility/dictation_test_utils.cc
@@ -179,7 +179,7 @@ // Increase Dictation's NO_FOCUSED_IME timeout to reduce flakiness on slower // builds. - std::string script = "testSupport.increaseNoFocusedImeTimeout();"; + std::string script = "testSupport.setNoFocusedImeTimeout(20 * 1000);"; ExecuteAccessibilityCommonScript(script); // Dictation will request a Pumpkin install when it starts up. Wait for
diff --git a/chrome/browser/ash/accessibility/dictation_test_utils.h b/chrome/browser/ash/accessibility/dictation_test_utils.h index 879e2e7a..ae7e6be5 100644 --- a/chrome/browser/ash/accessibility/dictation_test_utils.h +++ b/chrome/browser/ash/accessibility/dictation_test_utils.h
@@ -94,6 +94,10 @@ int GetCommitTextCallCount(); void WaitForCommitText(const std::u16string& value); + // TODO(b:259352600): Instead of disabling the observer, change this to + // allow specific messages. + void DisableConsoleObserver() { console_observer_.reset(); } + // Sets whether or not we should wait for the accessibility common extension // to load when enabling Dictation. This should be true in almost all cases. // However, there are times when we don't want to wait for accessibility
diff --git a/chrome/browser/ash/camera_mic/vm_camera_mic_manager.cc b/chrome/browser/ash/camera_mic/vm_camera_mic_manager.cc index ee3ac93..140b024 100644 --- a/chrome/browser/ash/camera_mic/vm_camera_mic_manager.cc +++ b/chrome/browser/ash/camera_mic/vm_camera_mic_manager.cc
@@ -366,7 +366,7 @@ } } - const raw_ptr<Profile, ExperimentalAsh> profile_; + const raw_ptr<Profile, LeakedDanglingUntriaged | ExperimentalAsh> profile_; const VmType vm_type_; const int name_id_; base::RepeatingClosure notification_changed_callback_;
diff --git a/chrome/browser/ash/camera_mic/vm_camera_mic_manager.h b/chrome/browser/ash/camera_mic/vm_camera_mic_manager.h index 983530694..334109b 100644 --- a/chrome/browser/ash/camera_mic/vm_camera_mic_manager.h +++ b/chrome/browser/ash/camera_mic/vm_camera_mic_manager.h
@@ -108,7 +108,8 @@ void UpdateVmInfo(VmType vm, void (VmInfo::*updator)(bool), bool value); void NotifyActiveChanged(); - raw_ptr<Profile, ExperimentalAsh> primary_profile_ = nullptr; + raw_ptr<Profile, LeakedDanglingUntriaged | ExperimentalAsh> primary_profile_ = + nullptr; std::map<VmType, VmInfo> vm_info_map_; base::ObserverList<Observer> observers_;
diff --git a/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.cc b/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.cc index 41140736..21a6bd4 100644 --- a/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.cc +++ b/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.cc
@@ -45,10 +45,11 @@ ClientAppMetadataProviderServiceFactory:: ~ClientAppMetadataProviderServiceFactory() = default; -KeyedService* ClientAppMetadataProviderServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ClientAppMetadataProviderServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* browser_context) const { Profile* profile = Profile::FromBrowserContext(browser_context); - return new ClientAppMetadataProviderService( + return std::make_unique<ClientAppMetadataProviderService>( profile->GetPrefs(), NetworkHandler::Get()->network_state_handler(), instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile)); }
diff --git a/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.h b/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.h index 39d1202..957fd8d 100644 --- a/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.h +++ b/chrome/browser/ash/cryptauth/client_app_metadata_provider_service_factory.h
@@ -33,7 +33,7 @@ ~ClientAppMetadataProviderServiceFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* browser_context) const override; };
diff --git a/chrome/browser/ash/extensions/default_keyboard_extension_browser_test.cc b/chrome/browser/ash/extensions/default_keyboard_extension_browser_test.cc index faa82a5..0583e8a 100644 --- a/chrome/browser/ash/extensions/default_keyboard_extension_browser_test.cc +++ b/chrome/browser/ash/extensions/default_keyboard_extension_browser_test.cc
@@ -14,9 +14,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" @@ -98,20 +95,14 @@ client->ShowKeyboard(); GURL url = extensions::Extension::GetBaseURLFromExtensionId(id); - std::unique_ptr<content::RenderWidgetHostIterator> widgets( - content::RenderWidgetHost::GetRenderWidgetHosts()); - while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { - content::RenderViewHost* view = content::RenderViewHost::From(widget); - if (!view) - continue; - content::WebContents* wc = content::WebContents::FromRenderViewHost(view); - if (wc && - url == wc->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL()) { + for (content::WebContents* wc : content::GetAllWebContents()) { + if (url == wc->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL()) { // Waits for virtual keyboard to load. EXPECT_TRUE(content::WaitForLoadStop(wc)); return wc; } } + LOG(ERROR) << "Extension not found:" << url; return nullptr; }
diff --git a/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc b/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc index 5b3879e..a03ae06 100644 --- a/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc +++ b/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc
@@ -685,8 +685,10 @@ warned_files_; storage::FileSystemURLSet directory_scanning_expectations_; std::unique_ptr<TestingProfileManager> profile_manager_; - raw_ptr<TestingProfile, DanglingUntriaged> profile_; - raw_ptr<policy::MockFilesPolicyNotificationManager, ExperimentalAsh> fpnm_; + raw_ptr<TestingProfile, DanglingUntriaged | DanglingUntriaged> profile_; + raw_ptr<policy::MockFilesPolicyNotificationManager, + DanglingUntriaged | ExperimentalAsh> + fpnm_; policy::OnDlpRestrictionCheckedCallback warning_callback_; };
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc index 8b0214dd..30edb294 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -133,9 +133,6 @@ #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" @@ -4049,29 +4046,7 @@ std::vector<content::WebContents*> FileManagerBrowserTestBase::GetAllWebContents() { - // Code borrowed from WebContentsImpl. - std::vector<content::WebContents*> result; - - std::unique_ptr<content::RenderWidgetHostIterator> widgets( - content::RenderWidgetHost::GetRenderWidgetHosts()); - while (content::RenderWidgetHost* rwh = widgets->GetNextHost()) { - content::RenderViewHost* rvh = content::RenderViewHost::From(rwh); - if (!rvh) { - continue; - } - content::WebContents* web_contents = - content::WebContents::FromRenderViewHost(rvh); - if (!web_contents) { - continue; - } - if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost() != rvh) { - continue; - } - // Because a WebContents can only have one current RVH at a time, there will - // be no duplicate WebContents here. - result.push_back(web_contents); - } - return result; + return content::GetAllWebContents(); } content::WebContents*
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_unittest.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_unittest.cc index 86921b35..6de3b88 100644 --- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_unittest.cc +++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_unittest.cc
@@ -353,7 +353,7 @@ scoped_refptr<testing::NiceMock<MockBluetoothAdapter>> mock_adapter_; raw_ptr<testing::StrictMock<MockEasyUnlockNotificationController>, - ExperimentalAsh> + DanglingUntriaged | ExperimentalAsh> mock_notification_controller_; views::TestViewsDelegate view_delegate_;
diff --git a/chrome/browser/ash/login/session/user_session_manager.h b/chrome/browser/ash/login/session/user_session_manager.h index 8475008..0433f74 100644 --- a/chrome/browser/ash/login/session/user_session_manager.h +++ b/chrome/browser/ash/login/session/user_session_manager.h
@@ -545,7 +545,8 @@ base::WeakPtr<UserSessionManagerDelegate> delegate_; // Used to listen to network changes. - raw_ptr<network::NetworkConnectionTracker, ExperimentalAsh> + raw_ptr<network::NetworkConnectionTracker, + LeakedDanglingUntriaged | ExperimentalAsh> network_connection_tracker_; // Authentication/user context.
diff --git a/chrome/browser/ash/login/ui/user_adding_screen_input_methods_controller.h b/chrome/browser/ash/login/ui/user_adding_screen_input_methods_controller.h index 2ea5a53a..c14d44744 100644 --- a/chrome/browser/ash/login/ui/user_adding_screen_input_methods_controller.h +++ b/chrome/browser/ash/login/ui/user_adding_screen_input_methods_controller.h
@@ -34,10 +34,11 @@ void OnUserAddingFinished() override; private: - raw_ptr<UserAddingScreen, ExperimentalAsh> screen_; + raw_ptr<UserAddingScreen, DanglingUntriaged | ExperimentalAsh> screen_; scoped_refptr<input_method::InputMethodManager::State> saved_ime_state_; - raw_ptr<user_manager::User, ExperimentalAsh> active_user_on_show_; + raw_ptr<user_manager::User, DanglingUntriaged | ExperimentalAsh> + active_user_on_show_; }; } // namespace ash
diff --git a/chrome/browser/ash/net/network_diagnostics/network_diagnostics.h b/chrome/browser/ash/net/network_diagnostics/network_diagnostics.h index 7136e69..ad82a2d 100644 --- a/chrome/browser/ash/net/network_diagnostics/network_diagnostics.h +++ b/chrome/browser/ash/net/network_diagnostics/network_diagnostics.h
@@ -73,7 +73,8 @@ RoutineResultCallback callback, chromeos::network_diagnostics::mojom::RoutineResultPtr result); // An unowned pointer to the DebugDaemonClient instance. - raw_ptr<DebugDaemonClient, ExperimentalAsh> debug_daemon_client_; + raw_ptr<DebugDaemonClient, LeakedDanglingUntriaged | ExperimentalAsh> + debug_daemon_client_; // Receiver for mojo service manager service provider. mojo::Receiver<chromeos::mojo_service_manager::mojom::ServiceProvider> provider_receiver_{this};
diff --git a/chrome/browser/ash/notifications/update_notification_showing_controller.h b/chrome/browser/ash/notifications/update_notification_showing_controller.h index 7160e5a..17b430f 100644 --- a/chrome/browser/ash/notifications/update_notification_showing_controller.h +++ b/chrome/browser/ash/notifications/update_notification_showing_controller.h
@@ -45,7 +45,7 @@ void SetFakeCurrentMilestoneForTesting(int fake_milestone); int current_milestone_; - const raw_ptr<Profile, ExperimentalAsh> profile_; + const raw_ptr<Profile, LeakedDanglingUntriaged | ExperimentalAsh> profile_; std::unique_ptr<UpdateNotification> update_notification_; };
diff --git a/chrome/browser/ash/policy/dlp/files_policy_notification_manager.h b/chrome/browser/ash/policy/dlp/files_policy_notification_manager.h index 0d7ee1d..671d550 100644 --- a/chrome/browser/ash/policy/dlp/files_policy_notification_manager.h +++ b/chrome/browser/ash/policy/dlp/files_policy_notification_manager.h
@@ -396,7 +396,8 @@ base::OnceCallback<void(gfx::NativeWindow)> pending_callback_; // Context for which the FPNM is created. - raw_ptr<content::BrowserContext, ExperimentalAsh> context_; + raw_ptr<content::BrowserContext, DanglingUntriaged | ExperimentalAsh> + context_; // A map from tracked IO tasks ids to their info. std::map<file_manager::io_task::IOTaskId, FileTaskInfo> io_tasks_;
diff --git a/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc b/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc index 1951e1b1..3eb881b 100644 --- a/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc +++ b/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc
@@ -986,7 +986,9 @@ ASSERT_EQ(first_app, FindFilesApp()); // The first notification should be closed. - EXPECT_FALSE(bridge_->GetDisplayedNotification(kNotificationId1).has_value()); + // TODO(b/297031519): Uncomment after investigating test failures. + // EXPECT_FALSE( + // bridge_->GetDisplayedNotification(kNotificationId1).has_value()); // Show the second dialog. ASSERT_TRUE(bridge_->GetDisplayedNotification(kNotificationId2).has_value()); @@ -997,7 +999,9 @@ ASSERT_EQ(first_app, FindFilesApp()); // The notification should be closed. - EXPECT_FALSE(bridge_->GetDisplayedNotification(kNotificationId2).has_value()); + // TODO(b/297031519): Uncomment after investigating test failures. + // EXPECT_FALSE( + // bridge_->GetDisplayedNotification(kNotificationId2).has_value()); histogram_tester_.ExpectBucketCount( GetDlpHistogramPrefix() + dlp::kFilesAppOpenTimedOutUMA, false, 1);
diff --git a/chrome/browser/ash/printing/print_servers_provider.cc b/chrome/browser/ash/printing/print_servers_provider.cc index 1b20295..ad6fc1e 100644 --- a/chrome/browser/ash/printing/print_servers_provider.cc +++ b/chrome/browser/ash/printing/print_servers_provider.cc
@@ -324,7 +324,8 @@ // The current resultant list of servers. std::vector<PrintServer> result_servers_; - raw_ptr<PrefService, ExperimentalAsh> prefs_ = nullptr; + raw_ptr<PrefService, LeakedDanglingUntriaged | ExperimentalAsh> prefs_ = + nullptr; PrefChangeRegistrar pref_change_registrar_; std::string allowlist_pref_;
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc b/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc index 78b2eab7..420d8fb 100644 --- a/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc +++ b/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/ash/printing/synced_printers_manager_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" @@ -95,7 +96,6 @@ static const base::NoDestructor<base::flat_map<ActionType, std::string>> action_type_urls( {{ActionType::kOpenChrome, "chrome://new-tab-page/"}, - {ActionType::kOpenPersonalizationApp, "chrome://personalization/"}, {ActionType::kOpenPlayStore, "https://play.google.com/store/games?device=chromebook"}, {ActionType::kOpenGoogleDocs, @@ -175,20 +175,6 @@ crosapi::UrlHandlerAsh().OpenUrl(sanitized_url); return; } - - // TODO(b/291771298): Opening personalization hub links doesn't work in - // the lacros browser so we need to handle it separately. - if (url.spec() == - GetActionTypeURLs().at(ActionType::kOpenPersonalizationApp)) { - NavigateParams navigate_params( - profile, url, - ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | - ui::PAGE_TRANSITION_FROM_API)); - navigate_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; - navigate_params.window_action = NavigateParams::SHOW_WINDOW; - Navigate(&navigate_params); - return; - } } ash::NewWindowDelegate::GetPrimary()->OpenUrl( @@ -435,9 +421,8 @@ break; } case ActionType::kOpenPersonalizationApp: { - OpenUrlForProfile( - profile_, - GURL(GetActionTypeURLs().at(ActionType::kOpenPersonalizationApp))); + ash::LaunchSystemWebAppAsync(profile_, + ash::SystemWebAppType::PERSONALIZATION); break; } case ActionType::kOpenPlayStore: {
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc index 2635e2d..249e02d 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.cc
@@ -369,7 +369,6 @@ // UpdateSettings assumes that ambient is enabled. Since ambient is now // disabled, cancel any requests to update settings. write_weak_factory_.InvalidateWeakPtrs(); - has_pending_updates_for_backend_ = false; is_updating_backend_ = false; } } @@ -518,13 +517,9 @@ // Prevent fetch settings callback changing `settings_` and `personal_albums_` // while updating. read_weak_factory_.InvalidateWeakPtrs(); + // Cancel in-flight write requests, as this newer update will overwrite them. + write_weak_factory_.InvalidateWeakPtrs(); - if (is_updating_backend_) { - has_pending_updates_for_backend_ = true; - return; - } - - has_pending_updates_for_backend_ = false; is_updating_backend_ = true; // Explicitly set show_weather to true to force server to respond with @@ -566,11 +561,7 @@ const bool need_retry_update_settings_at_backend = !success && update_settings_retry_backoff_.failure_count() <= kMaxRetries; - // If there has pending updates or need to retry, then updates settings again. - const bool should_update_settings_at_backend = - has_pending_updates_for_backend_ || need_retry_update_settings_at_backend; - - if (!should_update_settings_at_backend) { + if (!need_retry_update_settings_at_backend) { return false; } @@ -757,7 +748,6 @@ fetch_settings_retry_backoff_.Reset(); has_pending_fetch_request_ = false; is_updating_backend_ = false; - has_pending_updates_for_backend_ = false; } void PersonalizationAppAmbientProviderImpl::StartScreenSaverPreview() {
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h index 4dd3707d..3ac4b40 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl.h
@@ -164,9 +164,6 @@ // Whether the Settings updating is ongoing. bool is_updating_backend_ = false; - // Whether there are pending updates. - bool has_pending_updates_for_backend_ = false; - // Whether to update previews when `UpdateSettings()` returns successfully. bool needs_update_previews_ = false;
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc index 4fba79c..650e0c49 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_ambient_provider_impl_unittest.cc
@@ -349,10 +349,6 @@ return ambient_provider_->is_updating_backend_; } - bool HasPendingUpdatesAtProvider() const { - return ambient_provider_->has_pending_updates_for_backend_; - } - base::TimeDelta GetFetchSettingsDelay() { return ambient_provider_->fetch_settings_retry_backoff_ .GetTimeUntilRelease(); @@ -473,21 +469,6 @@ } TEST_F(PersonalizationAppAmbientProviderImplTest, - OnAmbientModeEnabled_ShouldCancelPendingUpdateSettingsRequest) { - PrefService* pref_service = profile()->GetPrefs(); - EXPECT_TRUE(pref_service); - UpdateSettings(); - UpdateSettings(); - // The second call creates pending updates for the provider. - EXPECT_TRUE(HasPendingUpdatesAtProvider()); - - pref_service->SetBoolean(ash::ambient::prefs::kAmbientModeEnabled, false); - - EXPECT_FALSE(HasPendingUpdatesAtProvider()); - EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); -} - -TEST_F(PersonalizationAppAmbientProviderImplTest, OnAmbientModeEnabled_ShouldCancelDelayedUpdateSettingsRequest) { PrefService* pref_service = profile()->GetPrefs(); EXPECT_TRUE(pref_service); @@ -502,7 +483,6 @@ FastForwardBy(delay1 * 1.5); // Since ambient mode has been disabled, the pending update has been cleared. EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); } TEST_F(PersonalizationAppAmbientProviderImplTest, @@ -747,32 +727,40 @@ UpdateSettings(); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/true); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); } -TEST_F(PersonalizationAppAmbientProviderImplTest, TestUpdateSettingsTwice) { - UpdateSettings(); - EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); - EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); +TEST_F(PersonalizationAppAmbientProviderImplTest, + TestUpdateSettingsTwice_CancelsPreviousRequests) { + SetAmbientObserver(); + FetchSettings(); + ReplyFetchSettingsAndAlbums(/*success=*/true); + EXPECT_EQ(ash::AmbientModeTemperatureUnit::kCelsius, + ObservedTemperatureUnit()); + EXPECT_EQ(ash::AmbientModeTemperatureUnit::kCelsius, + GetCurrentTemperatureUnitInServer()); - UpdateSettings(); + SetTemperatureUnit(ash::AmbientModeTemperatureUnit::kFahrenheit); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_TRUE(HasPendingUpdatesAtProvider()); + + SetTemperatureUnit(ash::AmbientModeTemperatureUnit::kCelsius); + EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); + EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); ReplyUpdateSettings(/*success=*/true); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_TRUE(HasPendingUpdatesAtProvider()); - FastForwardBy(GetUpdateSettingsDelay() * 1.5); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); + // The newer temperature unit is used. The second call to UpdateSettings + // cancels the first request. + EXPECT_EQ(ash::AmbientModeTemperatureUnit::kCelsius, + ObservedTemperatureUnit()); + EXPECT_EQ(ash::AmbientModeTemperatureUnit::kCelsius, + GetCurrentTemperatureUnitInServer()); } TEST_F(PersonalizationAppAmbientProviderImplTest, @@ -780,17 +768,14 @@ UpdateSettings(); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); FastForwardBy(GetUpdateSettingsDelay() * 1.5); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); } TEST_F(PersonalizationAppAmbientProviderImplTest, @@ -798,23 +783,19 @@ UpdateSettings(); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); base::TimeDelta delay1 = GetUpdateSettingsDelay(); FastForwardBy(delay1 * 1.5); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); base::TimeDelta delay2 = GetUpdateSettingsDelay(); EXPECT_GT(delay2, delay1); @@ -822,7 +803,6 @@ FastForwardBy(delay2 * 1.5); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); } TEST_F(PersonalizationAppAmbientProviderImplTest, @@ -830,51 +810,42 @@ UpdateSettings(); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); // 1st retry. FastForwardBy(GetUpdateSettingsDelay() * 1.5); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); // 2nd retry. FastForwardBy(GetUpdateSettingsDelay() * 1.5); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); // 3rd retry. FastForwardBy(GetUpdateSettingsDelay() * 1.5); EXPECT_TRUE(IsUpdateSettingsPendingAtBackend()); EXPECT_TRUE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); ReplyUpdateSettings(/*success=*/false); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); // Will not retry. FastForwardBy(GetUpdateSettingsDelay() * 1.5); EXPECT_FALSE(IsUpdateSettingsPendingAtBackend()); EXPECT_FALSE(IsUpdateSettingsPendingAtProvider()); - EXPECT_FALSE(HasPendingUpdatesAtProvider()); } TEST_F(PersonalizationAppAmbientProviderImplTest,
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_bridge_unittest.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_bridge_unittest.cc index eb3e2bd..ef4098f 100644 --- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_bridge_unittest.cc +++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_bridge_unittest.cc
@@ -264,7 +264,7 @@ &mojo_wilco_dtc_supportd_service_}; raw_ptr<StrictMock<MockWilcoDtcSupportdNotificationController>, - ExperimentalAsh> + DanglingUntriaged | ExperimentalAsh> notification_controller_; std::unique_ptr<WilcoDtcSupportdBridge> wilco_dtc_supportd_bridge_;
diff --git a/chrome/browser/back_press/android/BUILD.gn b/chrome/browser/back_press/android/BUILD.gn index 639a2bc0..3364e9e 100644 --- a/chrome/browser/back_press/android/BUILD.gn +++ b/chrome/browser/back_press/android/BUILD.gn
@@ -42,6 +42,7 @@ "//chrome/browser/flags:java", "//components/browser_ui/widget/android:java", "//third_party/androidx:androidx_activity_activity_java", + "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", "//third_party/junit:junit",
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java index 6d987ac..876f24a 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java
@@ -7,6 +7,7 @@ import android.text.format.DateUtils; import android.util.SparseIntArray; +import androidx.activity.BackEventCompat; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; @@ -69,9 +70,33 @@ } private final OnBackPressedCallback mCallback = new OnBackPressedCallback(false) { + private BackPressHandler mActiveHandler; + @Override public void handleOnBackPressed() { BackPressManager.this.handleBackPress(); + mActiveHandler = null; + } + + // Following methods are only triggered on API 34+. + @Override + public void handleOnBackStarted(@NonNull BackEventCompat backEvent) { + mActiveHandler = getEnabledBackPressHandler(); + assert mActiveHandler != null; + mActiveHandler.handleOnBackStarted(backEvent); + } + + @Override + public void handleOnBackCancelled() { + assert mActiveHandler != null; + mActiveHandler.handleOnBackCancelled(); + mActiveHandler = null; + } + + @Override + public void handleOnBackProgressed(@NonNull BackEventCompat backEvent) { + assert mActiveHandler != null; + mActiveHandler.handleOnBackProgressed(backEvent); } }; @@ -242,6 +267,20 @@ } } + @VisibleForTesting + BackPressHandler getEnabledBackPressHandler() { + for (int i = 0; i < mHandlers.length; i++) { + BackPressHandler handler = mHandlers[i]; + if (handler == null) continue; + Boolean enabled = handler.getHandleBackPressChangedSupplier().get(); + if (enabled != null && enabled) { + return handler; + } + } + assert false; + return null; + } + private void handleBackPress() { var failed = new ArrayList<String>(); for (int i = 0; i < mHandlers.length; i++) {
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java index 9b29f36b..683f55df 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java
@@ -6,10 +6,14 @@ import android.os.Build; +import androidx.activity.BackEventCompat; +import androidx.annotation.NonNull; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.robolectric.annotation.Config; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -41,6 +45,15 @@ public CallbackHelper getCallbackHelper() { return mCallbackHelper; } + + @Override + public void handleOnBackCancelled() {} + + @Override + public void handleOnBackProgressed(@NonNull BackEventCompat backEvent) {} + + @Override + public void handleOnBackStarted(@NonNull BackEventCompat backEvent) {} } @Test @@ -66,6 +79,8 @@ h1.getCallbackHelper().getCallCount()); h1.getHandleBackPressChangedSupplier().set(true); + Assert.assertEquals( + "Should return the active handler", h1, manager.getEnabledBackPressHandler()); Assert.assertTrue("Callback should be enabled if any of handlers are enabled", manager.getCallback().isEnabled()); manager.getCallback().handleOnBackPressed(); @@ -98,6 +113,8 @@ manager.getCallback().isEnabled()); h2.getHandleBackPressChangedSupplier().set(true); + Assert.assertEquals( + "Should return the first active handler", h2, manager.getEnabledBackPressHandler()); Assert.assertTrue("Callback should be enabled if any of handlers are enabled.", manager.getCallback().isEnabled()); @@ -127,6 +144,8 @@ h1.getHandleBackPressChangedSupplier().set(true); h2.getHandleBackPressChangedSupplier().set(true); manager.getCallback().handleOnBackPressed(); + Assert.assertEquals("Should return the active handler of higher priority", h1, + manager.getEnabledBackPressHandler()); Assert.assertEquals("Enabled handler of higher priority should intercept the back gesture", 1, h1.getCallbackHelper().getCallCount()); @@ -303,6 +322,70 @@ manager.getCallback().isEnabled()); } + @Test + public void testOnBackPressProgressed() { + BackPressManager manager = new BackPressManager(); + EmptyBackPressHandler h1 = Mockito.spy(new EmptyBackPressHandler()); + EmptyBackPressHandler h2 = Mockito.spy(new EmptyBackPressHandler()); + manager.addHandler(h1, 0); + manager.addHandler(h2, 1); + h1.getHandleBackPressChangedSupplier().set(false); + h2.getHandleBackPressChangedSupplier().set(true); + Assert.assertEquals( + "Should return the active handler", h2, manager.getEnabledBackPressHandler()); + var backEvent = new BackEventCompat(0, 0, 0, BackEventCompat.EDGE_LEFT); + manager.getCallback().handleOnBackStarted(backEvent); + Mockito.verify(h2).handleOnBackStarted(backEvent); + + backEvent = new BackEventCompat(1, 0, .5f, BackEventCompat.EDGE_LEFT); + manager.getCallback().handleOnBackProgressed(backEvent); + Mockito.verify(h2).handleOnBackProgressed(backEvent); + + backEvent = new BackEventCompat(2, 0, 1, BackEventCompat.EDGE_LEFT); + manager.getCallback().handleOnBackProgressed(backEvent); + Mockito.verify(h2).handleOnBackProgressed(backEvent); + + manager.getCallback().handleOnBackPressed(); + Mockito.verify(h2).handleBackPress(); + + Mockito.verify(h2, + Mockito.never().description( + "Cancelled should never be called if back is not cancelled")) + .handleOnBackCancelled(); + } + + @Test + public void testOnBackPressCancelled() { + BackPressManager manager = new BackPressManager(); + EmptyBackPressHandler h1 = Mockito.spy(new EmptyBackPressHandler()); + EmptyBackPressHandler h2 = Mockito.spy(new EmptyBackPressHandler()); + manager.addHandler(h1, 0); + manager.addHandler(h2, 1); + h1.getHandleBackPressChangedSupplier().set(false); + h2.getHandleBackPressChangedSupplier().set(true); + Assert.assertEquals( + "Should return the active handler", h2, manager.getEnabledBackPressHandler()); + var backEvent = new BackEventCompat(0, 0, 0, BackEventCompat.EDGE_LEFT); + manager.getCallback().handleOnBackStarted(backEvent); + Mockito.verify(h2).handleOnBackStarted(backEvent); + + backEvent = new BackEventCompat(1, 0, .5f, BackEventCompat.EDGE_LEFT); + manager.getCallback().handleOnBackProgressed(backEvent); + Mockito.verify(h2).handleOnBackProgressed(backEvent); + + backEvent = new BackEventCompat(2, 0, 1, BackEventCompat.EDGE_LEFT); + manager.getCallback().handleOnBackProgressed(backEvent); + Mockito.verify(h2).handleOnBackProgressed(backEvent); + + manager.getCallback().handleOnBackCancelled(); + Mockito.verify(h2).handleOnBackCancelled(); + + Mockito.verify(h2, + Mockito.never().description( + "handleBackPress should never be called if back is cancelled")) + .handleBackPress(); + } + private int getHandlerCount(BackPressManager manager) { int count = 0; for (BackPressHandler handler : manager.getHandlersForTesting()) {
diff --git a/chrome/browser/browsing_data/access_context_audit_service_factory.cc b/chrome/browser/browsing_data/access_context_audit_service_factory.cc index 0ac31c1..440f260 100644 --- a/chrome/browser/browsing_data/access_context_audit_service_factory.cc +++ b/chrome/browser/browsing_data/access_context_audit_service_factory.cc
@@ -31,11 +31,12 @@ GetInstance()->GetServiceForBrowserContext(profile, true)); } -KeyedService* AccessContextAuditServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AccessContextAuditServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { auto context_audit_service = std::make_unique<AccessContextAuditService>(); context_audit_service->Init(context->GetPath()); - return context_audit_service.release(); + return context_audit_service; } bool AccessContextAuditServiceFactory::ServiceIsCreatedWithBrowserContext()
diff --git a/chrome/browser/browsing_data/access_context_audit_service_factory.h b/chrome/browser/browsing_data/access_context_audit_service_factory.h index 3da99cc..27cbe48 100644 --- a/chrome/browser/browsing_data/access_context_audit_service_factory.h +++ b/chrome/browser/browsing_data/access_context_audit_service_factory.h
@@ -22,7 +22,7 @@ ~AccessContextAuditServiceFactory() override = default; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; };
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index 6830559..469300f 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -823,6 +823,7 @@ return browser_context; }, base::Unretained(GetBrowser()->profile())), + /*storage_partition_config=*/absl::nullopt, /*origin=*/origin, content::ClearSiteDataTypeSet::All(), /*storage_buckets_to_remove=*/storage_buckets_to_remove, /*avoid_closing_connections=*/true, @@ -1012,6 +1013,7 @@ return browser_context; }, base::Unretained(GetBrowser()->profile())), + /*storage_partition_config=*/absl::nullopt, /*origin=*/origin, clear_site_data_types, /*storage_buckets_to_remove=*/storage_buckets_to_remove, /*avoid_closing_connections=*/true,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index aefad7d..9b30ada 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -216,6 +216,7 @@ #include "components/embedder_support/origin_trials/origin_trials_settings_storage.h" #include "components/embedder_support/switches.h" #include "components/embedder_support/user_agent_utils.h" +#include "components/enterprise/common/proto/connectors.pb.h" #include "components/enterprise/content/clipboard_restriction_service.h" #include "components/enterprise/content/pref_names.h" #include "components/error_page/common/error.h" @@ -7384,6 +7385,9 @@ return; } + dialog_data.reason = + enterprise_connectors::ContentAnalysisRequest::CLIPBOARD_PASTE; + if (is_files) { auto string_paths = std::move(clipboard_paste_data.file_paths); std::vector<base::FilePath> paths;
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc index da8db93..7b91e6a 100644 --- a/chrome/browser/chrome_content_browser_client_browsertest.cc +++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -690,6 +690,78 @@ #if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) +class ClipboardTestContentAnalysisDelegate + : public enterprise_connectors::test::FakeContentAnalysisDelegate { + public: + ClipboardTestContentAnalysisDelegate(base::RepeatingClosure delete_closure, + StatusCallback status_callback, + std::string dm_token, + content::WebContents* web_contents, + Data data, + CompletionCallback callback) + : enterprise_connectors::test::FakeContentAnalysisDelegate( + delete_closure, + std::move(status_callback), + std::move(dm_token), + web_contents, + std::move(data), + std::move(callback)) {} + + static std::unique_ptr<ContentAnalysisDelegate> Create( + base::RepeatingClosure delete_closure, + StatusCallback status_callback, + std::string dm_token, + content::WebContents* web_contents, + Data data, + CompletionCallback callback) { + auto ret = std::make_unique<ClipboardTestContentAnalysisDelegate>( + delete_closure, std::move(status_callback), std::move(dm_token), + web_contents, std::move(data), std::move(callback)); + enterprise_connectors::FilesRequestHandler::SetFactoryForTesting( + base::BindRepeating( + &enterprise_connectors::test::FakeFilesRequestHandler::Create, + base::BindRepeating(&ClipboardTestContentAnalysisDelegate:: + FakeUploadFileForDeepScanning, + base::Unretained(ret.get())))); + return ret; + } + + private: + void UploadTextForDeepScanning( + std::unique_ptr<safe_browsing::BinaryUploadService::Request> request) + override { + ASSERT_EQ(request->reason(), + enterprise_connectors::ContentAnalysisRequest::CLIPBOARD_PASTE); + + enterprise_connectors::test::FakeContentAnalysisDelegate:: + UploadTextForDeepScanning(std::move(request)); + } + + void UploadImageForDeepScanning( + std::unique_ptr<safe_browsing::BinaryUploadService::Request> request) + override { + ASSERT_EQ(request->reason(), + enterprise_connectors::ContentAnalysisRequest::CLIPBOARD_PASTE); + + enterprise_connectors::test::FakeContentAnalysisDelegate:: + UploadImageForDeepScanning(std::move(request)); + } + + void FakeUploadFileForDeepScanning( + safe_browsing::BinaryUploadService::Result result, + const base::FilePath& path, + std::unique_ptr<safe_browsing::BinaryUploadService::Request> request, + enterprise_connectors::test::FakeFilesRequestHandler:: + FakeFileRequestCallback callback) override { + ASSERT_EQ(request->reason(), + enterprise_connectors::ContentAnalysisRequest::CLIPBOARD_PASTE); + + enterprise_connectors::test::FakeContentAnalysisDelegate:: + FakeUploadFileForDeepScanning(result, path, std::move(request), + std::move(callback)); + } +}; + class IsClipboardPasteContentAllowedTest : public InProcessBrowserTest { public: IsClipboardPasteContentAllowedTest() { @@ -709,8 +781,7 @@ enterprise_connectors::ContentAnalysisDelegate::SetFactoryForTesting( base::BindRepeating( - &enterprise_connectors::test::FakeContentAnalysisDelegate::Create, - base::DoNothing(), + &ClipboardTestContentAnalysisDelegate::Create, base::DoNothing(), base::BindRepeating([](const std::string& contents, const base::FilePath& path) { bool success = false;
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/cleanup/lacros_cleanup_handler_unittest.cc b/chrome/browser/chromeos/extensions/login_screen/login/cleanup/lacros_cleanup_handler_unittest.cc index 6484068..e5f961f 100644 --- a/chrome/browser/chromeos/extensions/login_screen/login/cleanup/lacros_cleanup_handler_unittest.cc +++ b/chrome/browser/chromeos/extensions/login_screen/login/cleanup/lacros_cleanup_handler_unittest.cc
@@ -55,7 +55,7 @@ absl::optional<std::string> error_; bool should_reset_ = false; raw_ptr<mojo::Receiver<crosapi::mojom::LacrosCleanupTriggeredObserver>, - ExperimentalAsh> + DanglingUntriaged | ExperimentalAsh> receiver_; };
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc index 4a9087e..1adac63 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -587,7 +587,7 @@ // MultiFileRequestHandler is owned by this class. files_request_handler_ = FilesRequestHandler::Create( GetBinaryUploadService(), profile_, data_.settings, url_, "", "", - user_action_id_, title_, access_point_, data_.paths, + user_action_id_, title_, access_point_, data_.reason, data_.paths, base::BindOnce(&ContentAnalysisDelegate::FilesRequestCallback, GetWeakPtr())); files_request_complete_ = !files_request_handler_->UploadData(); @@ -710,10 +710,18 @@ request->set_url(data_.url.spec()); request->set_tab_url(data_.url); request->set_per_profile_request(data_.settings.per_profile); - for (const auto& tag : data_.settings.tags) + + for (const auto& tag : data_.settings.tags) { request->add_tag(tag.first); - if (data_.settings.client_metadata) + } + + if (data_.settings.client_metadata) { request->set_client_metadata(*data_.settings.client_metadata); + } + + if (data_.reason != ContentAnalysisRequest::UNKNOWN) { + request->set_reason(data_.reason); + } } void ContentAnalysisDelegate::FillAllResultsWith(bool status) {
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h index 89aed6e..61ec7c2 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h
@@ -120,6 +120,12 @@ ContentMetaData::PrintMetadata::PrinterType printer_type = ContentMetaData::PrintMetadata::UNKNOWN; + // The reason the scanning should happen. This should be populated at the + // same time as fields like `text`, `paths`, `page`, etc. so that caller + // code can let enterprise code know the user action triggering content + // analysis. + ContentAnalysisRequest::Reason reason = ContentAnalysisRequest::UNKNOWN; + // The settings to use for the analysis of the data in this struct. AnalysisSettings settings; };
diff --git a/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc index 895b5c1..035adee 100644 --- a/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate.cc
@@ -370,7 +370,7 @@ // User action id and tab title are only needed for local content // analysis, leave them empty here. /*user_action_id=*/std::string(), /*tab_title=*/std::string(), - access_point_, std::move(paths), + access_point_, ContentAnalysisRequest::UNKNOWN, std::move(paths), base::BindOnce(&FileTransferAnalysisDelegate::ContentAnalysisCompleted, weak_ptr_factory_.GetWeakPtr())); request_handler_->UploadData();
diff --git a/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc b/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc index 2850684..67fc801 100644 --- a/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc +++ b/chrome/browser/enterprise/connectors/analysis/files_request_handler.cc
@@ -83,6 +83,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback) : RequestHandlerBase(upload_service, @@ -94,7 +95,8 @@ user_action_id, tab_title, paths.size(), - access_point), + access_point, + reason), paths_(paths), callback_(std::move(callback)) { results_.resize(paths_.size()); @@ -113,17 +115,20 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback) { if (GetFactoryStorage()->is_null()) { return base::WrapUnique(new FilesRequestHandler( upload_service, profile, analysis_settings, url, source, destination, - user_action_id, tab_title, access_point, paths, std::move(callback))); + user_action_id, tab_title, access_point, reason, paths, + std::move(callback))); } else { // Use the factory to create a fake FilesRequestHandler. - return GetFactoryStorage()->Run( - upload_service, profile, analysis_settings, url, source, destination, - user_action_id, tab_title, access_point, paths, std::move(callback)); + return GetFactoryStorage()->Run(upload_service, profile, analysis_settings, + url, source, destination, user_action_id, + tab_title, access_point, reason, paths, + std::move(callback)); } }
diff --git a/chrome/browser/enterprise/connectors/analysis/files_request_handler.h b/chrome/browser/enterprise/connectors/analysis/files_request_handler.h index 359b046f..2eaa569 100644 --- a/chrome/browser/enterprise/connectors/analysis/files_request_handler.h +++ b/chrome/browser/enterprise/connectors/analysis/files_request_handler.h
@@ -14,6 +14,7 @@ #include "chrome/browser/enterprise/connectors/analysis/request_handler_base.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h" #include "chrome/browser/safe_browsing/cloud_content_scanning/file_opening_job.h" +#include "components/enterprise/common/proto/connectors.pb.h" #include "components/file_access/scoped_file_access.h" namespace safe_browsing { @@ -64,6 +65,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback)>; @@ -82,6 +84,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback); @@ -105,6 +108,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback);
diff --git a/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc b/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc index c2a0015..f746ce29 100644 --- a/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc +++ b/chrome/browser/enterprise/connectors/analysis/files_request_handler_unittest.cc
@@ -216,7 +216,8 @@ settings->cloud_or_local_settings.is_cloud_analysis()), /*upload_service=*/nullptr, profile_, *settings, GURL(kTestUrl), "", "", kUserActionId, kTabTitle, - safe_browsing::DeepScanAccessPoint::UPLOAD, paths, + safe_browsing::DeepScanAccessPoint::UPLOAD, + ContentAnalysisRequest::FILE_PICKER_DIALOG, paths, future.GetCallback()); fake_files_request_handler_->UploadData();
diff --git a/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc b/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc index fdafb4b..b3640656 100644 --- a/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc +++ b/chrome/browser/enterprise/connectors/analysis/request_handler_base.cc
@@ -17,7 +17,8 @@ const std::string& user_action_id, const std::string& tab_title, uint64_t user_action_requests_count, - safe_browsing::DeepScanAccessPoint access_point) + safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason) : upload_service_(upload_service ? upload_service->AsWeakPtr() : nullptr), profile_(profile), analysis_settings_(analysis_settings), @@ -27,7 +28,8 @@ user_action_id_(user_action_id), tab_title_(tab_title), user_action_requests_count_(user_action_requests_count), - access_point_(access_point) {} + access_point_(access_point), + reason_(reason) {} RequestHandlerBase::~RequestHandlerBase() = default; @@ -67,10 +69,17 @@ request->set_destination(destination_); request->set_tab_url(url_); request->set_per_profile_request(analysis_settings_->per_profile); - for (const auto& tag : analysis_settings_->tags) + for (const auto& tag : analysis_settings_->tags) { request->add_tag(tag.first); - if (analysis_settings_->client_metadata) + } + + if (analysis_settings_->client_metadata) { request->set_client_metadata(*analysis_settings_->client_metadata); + } + + if (reason_ != ContentAnalysisRequest::UNKNOWN) { + request->set_reason(reason_); + } } safe_browsing::BinaryUploadService*
diff --git a/chrome/browser/enterprise/connectors/analysis/request_handler_base.h b/chrome/browser/enterprise/connectors/analysis/request_handler_base.h index ab11ba0..61adc33 100644 --- a/chrome/browser/enterprise/connectors/analysis/request_handler_base.h +++ b/chrome/browser/enterprise/connectors/analysis/request_handler_base.h
@@ -41,7 +41,8 @@ const std::string& user_action_id, const std::string& tab_title, uint64_t user_action_requests_count, - safe_browsing::DeepScanAccessPoint access_point); + safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason); virtual ~RequestHandlerBase(); @@ -95,6 +96,7 @@ std::string tab_title_; uint64_t user_action_requests_count_; safe_browsing::DeepScanAccessPoint access_point_; + ContentAnalysisRequest::Reason reason_; // A mapping of request tokens (corresponding to one user action) to their Ack // final action.
diff --git a/chrome/browser/enterprise/connectors/test/deep_scanning_browsertest_base.cc b/chrome/browser/enterprise/connectors/test/deep_scanning_browsertest_base.cc index 6641ed7..beb94768 100644 --- a/chrome/browser/enterprise/connectors/test/deep_scanning_browsertest_base.cc +++ b/chrome/browser/enterprise/connectors/test/deep_scanning_browsertest_base.cc
@@ -44,11 +44,13 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, FilesRequestHandler::CompletionCallback callback) { return base::WrapUnique(new UnresponsiveFilesRequestHandler( upload_service, profile, analysis_settings, url, source, destination, - user_action_id, tab_title, access_point, paths, std::move(callback))); + user_action_id, tab_title, access_point, reason, paths, + std::move(callback))); } private:
diff --git a/chrome/browser/enterprise/connectors/test/fake_content_analysis_delegate.h b/chrome/browser/enterprise/connectors/test/fake_content_analysis_delegate.h index bbda8914..3985cf4 100644 --- a/chrome/browser/enterprise/connectors/test/fake_content_analysis_delegate.h +++ b/chrome/browser/enterprise/connectors/test/fake_content_analysis_delegate.h
@@ -90,7 +90,7 @@ static bool WasDialogCanceled(); static int GetTotalAnalysisRequestsCount(); - private: + protected: // Simulates a response from the binary upload service. the |path| // argument is used to call |status_callback_| to determine if the path // should succeed or fail.
diff --git a/chrome/browser/enterprise/connectors/test/fake_files_request_handler.cc b/chrome/browser/enterprise/connectors/test/fake_files_request_handler.cc index 7327fe8..320ae5c 100644 --- a/chrome/browser/enterprise/connectors/test/fake_files_request_handler.cc +++ b/chrome/browser/enterprise/connectors/test/fake_files_request_handler.cc
@@ -19,6 +19,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback) : FilesRequestHandler(upload_service, @@ -30,6 +31,7 @@ user_action_id, tab_title, access_point, + reason, paths, std::move(callback)), fake_file_upload_callback_(fake_file_upload_callback) {} @@ -48,12 +50,13 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, FilesRequestHandler::CompletionCallback callback) { return std::make_unique<FakeFilesRequestHandler>( fake_file_upload_callback, upload_service, profile, analysis_settings, - url, source, destination, user_action_id, tab_title, access_point, paths, - std::move(callback)); + url, source, destination, user_action_id, tab_title, access_point, reason, + paths, std::move(callback)); } void FakeFilesRequestHandler::UploadFileForDeepScanning(
diff --git a/chrome/browser/enterprise/connectors/test/fake_files_request_handler.h b/chrome/browser/enterprise/connectors/test/fake_files_request_handler.h index 57aa3b1..abcbbe0d 100644 --- a/chrome/browser/enterprise/connectors/test/fake_files_request_handler.h +++ b/chrome/browser/enterprise/connectors/test/fake_files_request_handler.h
@@ -34,6 +34,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, CompletionCallback callback); @@ -50,6 +51,7 @@ const std::string& user_action_id, const std::string& tab_title, safe_browsing::DeepScanAccessPoint access_point, + ContentAnalysisRequest::Reason reason, const std::vector<base::FilePath>& paths, FilesRequestHandler::CompletionCallback callback);
diff --git a/chrome/browser/enterprise/idle/OWNERS b/chrome/browser/enterprise/idle/OWNERS index 033a14f..05da0de 100644 --- a/chrome/browser/enterprise/idle/OWNERS +++ b/chrome/browser/enterprise/idle/OWNERS
@@ -1 +1 @@ -nicolaso@chromium.org +file://components/enterprise/idle/OWNERS \ No newline at end of file
diff --git a/chrome/browser/enterprise/idle/action.cc b/chrome/browser/enterprise/idle/action.cc index 4b5b3dc..270a964 100644 --- a/chrome/browser/enterprise/idle/action.cc +++ b/chrome/browser/enterprise/idle/action.cc
@@ -19,7 +19,7 @@ #include "chrome/browser/enterprise/idle/action_runner.h" #include "chrome/browser/enterprise/idle/idle_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browsing_data_remover.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/enterprise/idle/action.h b/chrome/browser/enterprise/idle/action.h index 7dbde4a2..eb55d34 100644 --- a/chrome/browser/enterprise/idle/action.h +++ b/chrome/browser/enterprise/idle/action.h
@@ -15,43 +15,13 @@ #include "base/no_destructor.h" #include "build/build_config.h" #include "chrome/browser/ui/idle_dialog.h" +#include "components/enterprise/idle/action_type.h" #include "content/public/browser/browsing_data_remover.h" class Profile; namespace enterprise_idle { -// Action types supported by IdleTimeoutActions. -// -// Actions run in order, based on their numerical value. Lower values run first. -// Keep this enum sorted by priority. -enum class ActionType { - kShowDialog = 0, // Not an IdleTimeoutAction value. Added as a side-effect. -#if !BUILDFLAG(IS_ANDROID) - kCloseBrowsers = 1, - kShowProfilePicker = 2, -#endif // !BUILDFLAG(IS_ANDROID) - kClearBrowsingHistory = 3, - kClearDownloadHistory, - kClearCookiesAndOtherSiteData, - kClearCachedImagesAndFiles, - kClearPasswordSignin, - kClearAutofill, - kClearSiteSettings, - kClearHostedAppData, - kReloadPages, - kShowBubble, // Not an IdleTimeoutAction value. Added as a side-effect. -}; - -// A mapping of names to enums, for the ConfigurationPolicyHandler to make -// conversions. -struct ActionTypeMapEntry { - const char* name; - ActionType action_type; -}; -extern const ActionTypeMapEntry kActionTypeMap[]; -extern const size_t kActionTypeMapSize; - // An action that should Run() when a given event happens. See *Actions // policies, e.g. IdleTimeoutActions. class Action {
diff --git a/chrome/browser/enterprise/idle/action_runner.cc b/chrome/browser/enterprise/idle/action_runner.cc index 09d6aa3f..8c6b3cd81 100644 --- a/chrome/browser/enterprise/idle/action_runner.cc +++ b/chrome/browser/enterprise/idle/action_runner.cc
@@ -9,7 +9,7 @@ #include "base/functional/bind.h" #include "base/ranges/algorithm.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/prefs/pref_service.h" namespace enterprise_idle {
diff --git a/chrome/browser/enterprise/idle/action_runner_unittest.cc b/chrome/browser/enterprise/idle/action_runner_unittest.cc index 07b029c..18890b4 100644 --- a/chrome/browser/enterprise/idle/action_runner_unittest.cc +++ b/chrome/browser/enterprise/idle/action_runner_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/enterprise/idle/action.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browsing_data_remover.h" #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/enterprise/idle/dialog_manager.cc b/chrome/browser/enterprise/idle/dialog_manager.cc index ab7a52a..32f5a2d 100644 --- a/chrome/browser/enterprise/idle/dialog_manager.cc +++ b/chrome/browser/enterprise/idle/dialog_manager.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/prefs/pref_service.h" namespace enterprise_idle {
diff --git a/chrome/browser/enterprise/idle/idle_service.cc b/chrome/browser/enterprise/idle/idle_service.cc index 41b2f64..58d663a2 100644 --- a/chrome/browser/enterprise/idle/idle_service.cc +++ b/chrome/browser/enterprise/idle/idle_service.cc
@@ -11,11 +11,11 @@ #include "base/functional/callback.h" #include "base/json/values_util.h" #include "base/task/single_thread_task_runner.h" -#include "chrome/browser/enterprise/idle/idle_features.h" #include "chrome/browser/enterprise/idle/idle_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" +#include "components/enterprise/idle/idle_features.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/prefs/pref_service.h" #include "ui/base/idle/idle.h" #include "ui/base/idle/idle_polling_service.h"
diff --git a/chrome/browser/enterprise/idle/idle_service_factory.cc b/chrome/browser/enterprise/idle/idle_service_factory.cc index d33290c..ec0cfa1 100644 --- a/chrome/browser/enterprise/idle/idle_service_factory.cc +++ b/chrome/browser/enterprise/idle/idle_service_factory.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/enterprise/idle/idle_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" namespace enterprise_idle {
diff --git a/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc b/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc index 55c77c03..0e839e3 100644 --- a/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc +++ b/chrome/browser/enterprise/idle/idle_service_interactive_uitest.cc
@@ -33,6 +33,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/testing_profile.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" #include "components/policy/core/browser/browser_policy_connector.h"
diff --git a/chrome/browser/extensions/api/user_scripts/user_scripts_apitest.cc b/chrome/browser/extensions/api/user_scripts/user_scripts_apitest.cc index 9e2387b9..ac6dec5 100644 --- a/chrome/browser/extensions/api/user_scripts/user_scripts_apitest.cc +++ b/chrome/browser/extensions/api/user_scripts/user_scripts_apitest.cc
@@ -38,7 +38,11 @@ } IN_PROC_BROWSER_TEST_F(UserScriptsAPITest, RegisterUserScripts) { - ASSERT_TRUE(RunExtensionTest("user_scripts/")) << message_; + ASSERT_TRUE(RunExtensionTest("user_scripts/register")) << message_; +} + +IN_PROC_BROWSER_TEST_F(UserScriptsAPITest, GetUserScripts) { + ASSERT_TRUE(RunExtensionTest("user_scripts/get_scripts")) << message_; } } // namespace extensions
diff --git a/chrome/browser/extensions/blocklist_factory.cc b/chrome/browser/extensions/blocklist_factory.cc index 675eeb55..343505e 100644 --- a/chrome/browser/extensions/blocklist_factory.cc +++ b/chrome/browser/extensions/blocklist_factory.cc
@@ -40,9 +40,11 @@ BlocklistFactory::~BlocklistFactory() = default; -KeyedService* BlocklistFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +BlocklistFactory::BuildServiceInstanceForBrowserContext( BrowserContext* context) const { - return new Blocklist(Profile::FromBrowserContext(context)->GetPrefs()); + return std::make_unique<Blocklist>( + Profile::FromBrowserContext(context)->GetPrefs()); } } // namespace extensions
diff --git a/chrome/browser/extensions/blocklist_factory.h b/chrome/browser/extensions/blocklist_factory.h index 6d1401fc..dda1970 100644 --- a/chrome/browser/extensions/blocklist_factory.h +++ b/chrome/browser/extensions/blocklist_factory.h
@@ -28,7 +28,7 @@ ~BlocklistFactory() override; // BrowserContextKeyedServiceFactory - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/extensions/cws_info_service_factory.cc b/chrome/browser/extensions/cws_info_service_factory.cc index cf505df..44caac1 100644 --- a/chrome/browser/extensions/cws_info_service_factory.cc +++ b/chrome/browser/extensions/cws_info_service_factory.cc
@@ -41,12 +41,13 @@ DependsOn(extensions::ExtensionRegistryFactory::GetInstance()); } -KeyedService* CWSInfoServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +CWSInfoServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { if (base::FeatureList::IsEnabled(kCWSInfoService) == false) { return nullptr; } - return new CWSInfoService(Profile::FromBrowserContext(context)); + return std::make_unique<CWSInfoService>(Profile::FromBrowserContext(context)); } bool CWSInfoServiceFactory::ServiceIsCreatedWithBrowserContext() const {
diff --git a/chrome/browser/extensions/cws_info_service_factory.h b/chrome/browser/extensions/cws_info_service_factory.h index c2bb85716..13f498d 100644 --- a/chrome/browser/extensions/cws_info_service_factory.h +++ b/chrome/browser/extensions/cws_info_service_factory.h
@@ -35,7 +35,7 @@ ~CWSInfoServiceFactory() override = default; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/extensions/install_tracker_factory.cc b/chrome/browser/extensions/install_tracker_factory.cc index fcc7befa..b60271f5 100644 --- a/chrome/browser/extensions/install_tracker_factory.cc +++ b/chrome/browser/extensions/install_tracker_factory.cc
@@ -42,9 +42,11 @@ InstallTrackerFactory::~InstallTrackerFactory() = default; -KeyedService* InstallTrackerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +InstallTrackerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new InstallTracker(context, ExtensionPrefs::Get(context)); + return std::make_unique<InstallTracker>(context, + ExtensionPrefs::Get(context)); } } // namespace extensions
diff --git a/chrome/browser/extensions/install_tracker_factory.h b/chrome/browser/extensions/install_tracker_factory.h index b79dc9d..2098fc1 100644 --- a/chrome/browser/extensions/install_tracker_factory.h +++ b/chrome/browser/extensions/install_tracker_factory.h
@@ -31,7 +31,7 @@ ~InstallTrackerFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/feedback/feedback_uploader_factory_chrome.cc b/chrome/browser/feedback/feedback_uploader_factory_chrome.cc index e6e03922..090df21 100644 --- a/chrome/browser/feedback/feedback_uploader_factory_chrome.cc +++ b/chrome/browser/feedback/feedback_uploader_factory_chrome.cc
@@ -50,9 +50,10 @@ return true; } -KeyedService* FeedbackUploaderFactoryChrome::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +FeedbackUploaderFactoryChrome::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new FeedbackUploaderChrome(context); + return std::make_unique<FeedbackUploaderChrome>(context); } } // namespace feedback
diff --git a/chrome/browser/feedback/feedback_uploader_factory_chrome.h b/chrome/browser/feedback/feedback_uploader_factory_chrome.h index 95f0f48..2521211 100644 --- a/chrome/browser/feedback/feedback_uploader_factory_chrome.h +++ b/chrome/browser/feedback/feedback_uploader_factory_chrome.h
@@ -36,7 +36,7 @@ content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; bool ServiceIsNULLWhileTesting() const override; - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc index a293917..961f04a05 100644 --- a/chrome/browser/file_select_helper.cc +++ b/chrome/browser/file_select_helper.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/grit/generated_resources.h" #include "components/enterprise/buildflags/buildflags.h" +#include "components/enterprise/common/proto/connectors.pb.h" #include "components/safe_browsing/buildflags.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -341,6 +342,8 @@ if (enterprise_connectors::ContentAnalysisDelegate::IsEnabled( profile_, web_contents_->GetLastCommittedURL(), &data, enterprise_connectors::AnalysisConnector::FILE_ATTACHED)) { + data.reason = + enterprise_connectors::ContentAnalysisRequest::FILE_PICKER_DIALOG; data.paths.reserve(list.size()); for (const auto& file : list) { if (file && file->is_native_file())
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h index 78bf6b0..a905c94d 100644 --- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h +++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
@@ -150,11 +150,6 @@ enum class GrantType { kRead, kWrite }; - enum class PersistedPermissionOptions { - kDoNotUpdatePersistedPermission, - kUpdatePersistedPermission, - }; - // Converts permissions objects into a snapshot of grants categorized by // read/write and file/directory types. Currently, used in UI code. // Assumes that all objects are grants for the same origin. @@ -237,6 +232,11 @@ kExtended, }; + enum class PersistedPermissionOptions { + kDoNotUpdatePersistedPermission, + kUpdatePersistedPermission, + }; + // Retrieve the persisted grant state for all persisted grants for a given // origin. PersistedGrantState GetPersistedGrantState(const url::Origin& origin) const;
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc index a3d7ccd..dac8571 100644 --- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc +++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -54,8 +54,6 @@ using UserAction = ChromeFileSystemAccessPermissionContext::UserAction; using PermissionStatus = content::FileSystemAccessPermissionGrant::PermissionStatus; -using PersistedPermissionOptions = - ChromeFileSystemAccessPermissionContext::PersistedPermissionOptions; using PermissionRequestOutcome = content::FileSystemAccessPermissionGrant::PermissionRequestOutcome; using SensitiveDirectoryResult =
diff --git a/chrome/browser/first_run/android/BUILD.gn b/chrome/browser/first_run/android/BUILD.gn index bf2db93..a1f24a6 100644 --- a/chrome/browser/first_run/android/BUILD.gn +++ b/chrome/browser/first_run/android/BUILD.gn
@@ -10,6 +10,7 @@ "java/src/org/chromium/chrome/browser/firstrun/MobileFreProgress.java", ] deps = [ + "//base:base_java", "//chrome/browser/preferences:java", "//third_party/androidx:androidx_annotation_annotation_java", ]
diff --git a/chrome/browser/first_run/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java b/chrome/browser/first_run/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java index 46536c7c..12c3114 100644 --- a/chrome/browser/first_run/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java +++ b/chrome/browser/first_run/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
@@ -6,6 +6,7 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.base.ResettersForTesting; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -17,8 +18,7 @@ private static boolean sFirstRunTriggered; /** @param triggered whether the first run flow is triggered in the current browser session. */ - @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) - public static void setFirstRunTriggered(boolean triggered) { + static void setFirstRunTriggered(boolean triggered) { sFirstRunTriggered = triggered; } @@ -28,6 +28,15 @@ } /** + * Test only setter for #setFirstRunTriggered, which will be reset to false after test. + * @see #setFirstRunTriggered(boolean). + */ + public static void setFirstRunTriggeredForTesting(boolean triggered) { + setFirstRunTriggered(triggered); + ResettersForTesting.register(() -> sFirstRunTriggered = false); + } + + /** * Sets the "main First Run Experience flow complete" preference. * @param isComplete Whether the main First Run Experience flow is complete */
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index a36a01c9..6d8ac2a1 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -647,6 +647,11 @@ "expiry_milestone": 120 }, { + "name": "autofill-enable-server-iban", + "owners": [ "qihuizhao@google.com", "jsaul@google.com" ], + "expiry_milestone": 128 + }, + { "name": "autofill-enable-sticky-manual-fallback-for-cards", "owners": [ "siashah","siyua" ], "expiry_milestone": 116
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index a07110c2..df53300 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -519,6 +519,12 @@ "When enabled, some extra metrics logging for Autofill Downstream will " "start."; +const char kAutofillEnableServerIbanName[] = + "Enable server-based IBAN uploading and autofilling"; +const char kAutofillEnableServerIbanDescription[] = + "When enabled, Autofill will attempt to offer upload save for IBANs " + "(International Bank Account Numbers) and autofill server-based IBANs."; + const char kAutofillEnableStickyManualFallbackForCardsName[] = "Make manual fallback sticky for credit cards"; const char kAutofillEnableStickyManualFallbackForCardsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 94c5d975..e7c04e8 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -301,6 +301,9 @@ extern const char kAutofillEnableRemadeDownstreamMetricsName[]; extern const char kAutofillEnableRemadeDownstreamMetricsDescription[]; +extern const char kAutofillEnableServerIbanName[]; +extern const char kAutofillEnableServerIbanDescription[]; + extern const char kAutofillEnableStickyManualFallbackForCardsName[]; extern const char kAutofillEnableStickyManualFallbackForCardsDescription[];
diff --git a/chrome/browser/flags/android/cached_feature_flags.cc b/chrome/browser/flags/android/cached_feature_flags.cc index 73ec2c9..b0c2256 100644 --- a/chrome/browser/flags/android/cached_feature_flags.cc +++ b/chrome/browser/flags/android/cached_feature_flags.cc
@@ -8,8 +8,6 @@ #include "base/android/jni_string.h" #include "base/feature_list.h" -#include "content/public/browser/network_service_util.h" -#include "content/public/common/content_features.h" using base::android::ConvertJavaStringToUTF8; using base::android::ConvertUTF8ToJavaString; @@ -35,9 +33,3 @@ } // namespace android } // namespace chrome - -static jboolean JNI_CachedFeatureFlags_IsNetworkServiceWarmUpEnabled( - JNIEnv* env) { - return content::IsOutOfProcessNetworkService() && - base::FeatureList::IsEnabled(features::kWarmUpNetworkProcess); -}
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index c972e808..d736b51 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -9,7 +9,6 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.FieldTrialList; import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.NativeMethods; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -81,7 +80,6 @@ * Do not add new simple boolean flags here, use {@link #cacheNativeFlags} instead. */ public static void cacheAdditionalNativeFlags() { - cacheNetworkServiceWarmUpEnabled(); CachedFlagsSafeMode.getInstance().cacheSafeModeForCachedFlagsEnabled(); cacheReachedCodeProfilerTrialGroup(); @@ -125,24 +123,6 @@ } /** - * Cache whether warming up network service process is enabled, so that the value - * can be made available immediately on next start up. - */ - private static void cacheNetworkServiceWarmUpEnabled() { - SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceKeys.FLAGS_CACHED_NETWORK_SERVICE_WARM_UP_ENABLED, - CachedFeatureFlagsJni.get().isNetworkServiceWarmUpEnabled()); - } - - /** - * @return whether warming up network service is enabled. - */ - public static boolean isNetworkServiceWarmUpEnabled() { - return getConsistentBooleanValue( - ChromePreferenceKeys.FLAGS_CACHED_NETWORK_SERVICE_WARM_UP_ENABLED, false); - } - - /** * Caches the trial group of the reached code profiler feature to be using on next startup. */ private static void cacheReachedCodeProfilerTrialGroup() { @@ -315,9 +295,4 @@ static void setSafeModeExperimentEnabledForTesting(Boolean value) { CachedFlagsSafeMode.getInstance().setExperimentEnabledForTesting(value); } - - @NativeMethods - interface Natives { - boolean isNetworkServiceWarmUpEnabled(); - } }
diff --git a/chrome/browser/font_pref_change_notifier_factory.cc b/chrome/browser/font_pref_change_notifier_factory.cc index 54c96c7..91b7ea3d7 100644 --- a/chrome/browser/font_pref_change_notifier_factory.cc +++ b/chrome/browser/font_pref_change_notifier_factory.cc
@@ -32,8 +32,9 @@ return instance.get(); } -KeyedService* FontPrefChangeNotifierFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +FontPrefChangeNotifierFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new FontPrefChangeNotifier( + return std::make_unique<FontPrefChangeNotifier>( Profile::FromBrowserContext(context)->GetPrefs()); }
diff --git a/chrome/browser/font_pref_change_notifier_factory.h b/chrome/browser/font_pref_change_notifier_factory.h index a67d04c4..28d953a 100644 --- a/chrome/browser/font_pref_change_notifier_factory.h +++ b/chrome/browser/font_pref_change_notifier_factory.h
@@ -25,7 +25,7 @@ ~FontPrefChangeNotifierFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/TabOnBackGestureHandler.java b/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/TabOnBackGestureHandler.java index 29c2e6d..8e7fb03 100644 --- a/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/TabOnBackGestureHandler.java +++ b/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/TabOnBackGestureHandler.java
@@ -28,17 +28,18 @@ private TabOnBackGestureHandler(Tab tab) { mNativePtr = TabOnBackGestureHandlerJni.get().init(tab); } - void onBackStarted(float x, float y, float progress, @BackGestureEventSwipeEdge int edge, + public void onBackStarted(float x, float y, float progress, @BackGestureEventSwipeEdge int edge, boolean forward) { TabOnBackGestureHandlerJni.get().onBackStarted(mNativePtr, x, y, progress, edge, forward); } - void onBackProgressed(float x, float y, float progress, @BackGestureEventSwipeEdge int edge) { + public void onBackProgressed( + float x, float y, float progress, @BackGestureEventSwipeEdge int edge) { TabOnBackGestureHandlerJni.get().onBackProgressed(mNativePtr, x, y, progress, edge); } - void onBackCancelled() { + public void onBackCancelled() { TabOnBackGestureHandlerJni.get().onBackCancelled(mNativePtr); } - void onBackInvoked() { + public void onBackInvoked() { TabOnBackGestureHandlerJni.get().onBackInvoked(mNativePtr); } @Override
diff --git a/chrome/browser/hid/hid_connection_tracker_factory.cc b/chrome/browser/hid/hid_connection_tracker_factory.cc index f19841f..7cfc900 100644 --- a/chrome/browser/hid/hid_connection_tracker_factory.cc +++ b/chrome/browser/hid/hid_connection_tracker_factory.cc
@@ -38,9 +38,11 @@ HidConnectionTrackerFactory::~HidConnectionTrackerFactory() = default; -KeyedService* HidConnectionTrackerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +HidConnectionTrackerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new HidConnectionTracker(Profile::FromBrowserContext(context)); + return std::make_unique<HidConnectionTracker>( + Profile::FromBrowserContext(context)); } void HidConnectionTrackerFactory::BrowserContextShutdown(
diff --git a/chrome/browser/hid/hid_connection_tracker_factory.h b/chrome/browser/hid/hid_connection_tracker_factory.h index cfd85e2..98cc73c 100644 --- a/chrome/browser/hid/hid_connection_tracker_factory.h +++ b/chrome/browser/hid/hid_connection_tracker_factory.h
@@ -26,7 +26,7 @@ ~HidConnectionTrackerFactory() override; // BrowserContextKeyedBaseFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; void BrowserContextShutdown(content::BrowserContext* context) override; };
diff --git a/chrome/browser/language/url_language_histogram_factory.cc b/chrome/browser/language/url_language_histogram_factory.cc index 3e7980c..43f7554 100644 --- a/chrome/browser/language/url_language_histogram_factory.cc +++ b/chrome/browser/language/url_language_histogram_factory.cc
@@ -35,10 +35,11 @@ UrlLanguageHistogramFactory::~UrlLanguageHistogramFactory() = default; -KeyedService* UrlLanguageHistogramFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +UrlLanguageHistogramFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* const browser_context) const { Profile* const profile = Profile::FromBrowserContext(browser_context); - return new language::UrlLanguageHistogram(profile->GetPrefs()); + return std::make_unique<language::UrlLanguageHistogram>(profile->GetPrefs()); } void UrlLanguageHistogramFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/language/url_language_histogram_factory.h b/chrome/browser/language/url_language_histogram_factory.h index 2905a84..521f3aec 100644 --- a/chrome/browser/language/url_language_histogram_factory.h +++ b/chrome/browser/language/url_language_histogram_factory.h
@@ -37,7 +37,7 @@ ~UrlLanguageHistogramFactory() override; // BrowserContextKeyedServiceFactory overrides. - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/media/cast_mirroring_service_host.cc b/chrome/browser/media/cast_mirroring_service_host.cc index 1d02c60..8a096af 100644 --- a/chrome/browser/media/cast_mirroring_service_host.cc +++ b/chrome/browser/media/cast_mirroring_service_host.cc
@@ -20,10 +20,12 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/media/cast_remoting_connector.h" #include "chrome/browser/media/router/discovery/access_code/access_code_cast_feature.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/tab_sharing/tab_sharing_ui.h" #include "components/access_code_cast/common/access_code_cast_metrics.h" #include "components/mirroring/browser/single_client_video_capture_host.h" @@ -147,14 +149,21 @@ id.main_render_frame_id)); } +// Gets the profile associated with `web_contents`, if it exists. Else, gets the +// last used profile if it is loaded. +Profile* GetProfileOrLastUsedProfile(content::WebContents* web_contents) { + if (web_contents) { + return Profile::FromBrowserContext(web_contents->GetBrowserContext()); + } + return ProfileManager::GetLastUsedProfileIfLoaded(); +} + // Returns true if this user is allowed to use Access Codes & QR codes to // discover cast devices, and AccessCodeCastTabSwitchingUI flag is enabled. bool IsAccessCodeCastTabSwitchingUIEnabled( const content::WebContentsMediaCaptureId& id) { - auto* web_contents = GetContents(id); - return web_contents && - media_router::IsAccessCodeCastTabSwitchingUiEnabled( - Profile::FromBrowserContext(web_contents->GetBrowserContext())); + Profile* profile = GetProfileOrLastUsedProfile(GetContents(id)); + return media_router::IsAccessCodeCastTabSwitchingUiEnabled(profile); } // Returns the size of the primary display in pixels, or absl::nullopt if it @@ -200,6 +209,13 @@ return; } + // If the target playout delay has not yet been set (from site-initiated + // mirroring request) then try to set it from a feature or commandline. + if (!session_params->target_playout_delay) { + session_params->target_playout_delay = + media_router::GetCastMirroringPlayoutDelay(); + } + // Although the base::Features get propagated to the mirroring service, the // command line flags do not. const base::CommandLine& command_line =
diff --git a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc index 8c15dae..3f55b1d 100644 --- a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc +++ b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc
@@ -6,12 +6,15 @@ #include "base/containers/contains.h" #include "base/containers/flat_map.h" +#include "base/json/json_reader.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/task/bind_post_task.h" #include "base/test/test_timeouts.h" #include "build/build_config.h" #include "chrome/browser/media/router/discovery/access_code/access_code_cast_feature.h" +#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_enums.h" @@ -20,6 +23,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/test/base/in_process_browser_test.h" +#include "components/media_router/common/pref_names.h" #include "components/mirroring/mojom/cast_message_channel.mojom.h" #include "components/mirroring/mojom/session_observer.mojom.h" #include "components/mirroring/mojom/session_parameters.mojom.h" @@ -148,6 +152,19 @@ const base::UnguessableToken session_id_ = base::UnguessableToken::Create(); }; +class MockCastMessageChannel : public mojom::CastMessageChannel { + public: + // mojom::CastMessageChannel mock implementation (outbound messages). + MOCK_METHOD(void, OnMessage, (mojom::CastMessagePtr)); + + mojo::Receiver<mojom::CastMessageChannel>* GetChannelReceiver() { + return &channel_receiver_; + } + + private: + mojo::Receiver<mojom::CastMessageChannel> channel_receiver_{this}; +}; + } // namespace class CastMirroringServiceHostBrowserTest @@ -176,7 +193,8 @@ mojo::PendingRemote<mojom::SessionObserver> observer; observer_receiver_.Bind(observer.InitWithNewPipeAndPassReceiver()); mojo::PendingRemote<mojom::CastMessageChannel> outbound_channel; - outbound_channel_receiver_.Bind( + outbound_channel_receiver_ = std::make_unique<MockCastMessageChannel>(); + outbound_channel_receiver_->GetChannelReceiver()->Bind( outbound_channel.InitWithNewPipeAndPassReceiver()); auto session_params = mojom::SessionParameters::New(); session_params->source_id = "SourceID"; @@ -185,6 +203,66 @@ inbound_channel_.BindNewPipeAndPassReceiver(), "Sink Name"); } + // Starts a tab mirroring session, and sets a target playout delay. + // `media_source_delay` simulates the mirroring delay that is set from a media + // source when starting a mirroring session, i.e. set by a site-initiated + // mirroring source. `feature_delay` is the value that media_router_feature's + // `GetCastMirroringPlayoutDelay` is expected to return. + void StartTabMirroringWithTargetPlayoutDelay( + base::TimeDelta media_source_delay, + base::TimeDelta feature_delay) { + int expected_delay_ms = !media_source_delay.is_zero() + ? media_source_delay.InMilliseconds() + : feature_delay.InMilliseconds(); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + host_ = std::make_unique<CastMirroringServiceHost>( + BuildMediaIdForTabMirroring(web_contents)); + mojo::PendingRemote<mojom::SessionObserver> observer; + observer_receiver_.Bind(observer.InitWithNewPipeAndPassReceiver()); + mojo::PendingRemote<mojom::CastMessageChannel> outbound_channel; + outbound_channel_receiver_ = std::make_unique<MockCastMessageChannel>(); + outbound_channel_receiver_->GetChannelReceiver()->Bind( + outbound_channel.InitWithNewPipeAndPassReceiver()); + auto session_params = mojom::SessionParameters::New(); + session_params->source_id = "SourceID"; + if (!media_source_delay.is_zero()) { + session_params->target_playout_delay = media_source_delay; + } + + base::RunLoop run_loop; + EXPECT_CALL(*outbound_channel_receiver_, OnMessage(_)) + .WillOnce( + testing::Invoke([expected_delay_ms, &run_loop]( + mirroring::mojom::CastMessagePtr message) { + const absl::optional<base::Value> root_or_error = + base::JSONReader::Read(message->json_format_data); + ASSERT_TRUE(root_or_error); + const base::Value::Dict& root = root_or_error->GetDict(); + const std::string* type = root.FindString("type"); + ASSERT_TRUE(type); + if (*type == "OFFER") { + const base::Value::Dict* offer = root.FindDict("offer"); + EXPECT_TRUE(offer); + const base::Value::List* streams = + offer->FindList("supportedStreams"); + for (auto& stream : *streams) { + const base::Value::Dict& stream_dict = stream.GetDict(); + const int stream_target_delay = + stream_dict.FindInt("targetDelay").value(); + EXPECT_EQ(stream_target_delay, expected_delay_ms); + } + } + run_loop.Quit(); + })); + host_->Start(std::move(session_params), std::move(observer), + std::move(outbound_channel), + inbound_channel_.BindNewPipeAndPassReceiver(), "Sink Name"); + run_loop.Run(); + } + void EnableAccessCodeCast() { ASSERT_FALSE(media_router::GetAccessCodeCastEnabledPref( browser()->tab_strip_model()->profile())); @@ -305,12 +383,12 @@ } mojo::Receiver<mojom::SessionObserver> observer_receiver_{this}; - mojo::Receiver<mojom::CastMessageChannel> outbound_channel_receiver_{this}; mojo::Receiver<mojom::AudioStreamCreatorClient> audio_client_receiver_{this}; mojo::Remote<mojom::CastMessageChannel> inbound_channel_; std::unique_ptr<CastMirroringServiceHost> host_; std::unique_ptr<MockVideoCaptureObserver> video_frame_receiver_; + std::unique_ptr<MockCastMessageChannel> outbound_channel_receiver_; }; IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTest, CaptureTabVideo) { @@ -388,6 +466,16 @@ StopMirroring(); } +IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTest, + TabMirrorWithPresetPlayoutDelay) { + StartTabMirroringWithTargetPlayoutDelay(base::Milliseconds(200), + base::Milliseconds(0)); + GetVideoCaptureHost(); + StartVideoCapturing(); + RequestRefreshFrame(); + StopMirroring(); +} + class CastMirroringServiceHostBrowserTestTabSwitcher : public CastMirroringServiceHostBrowserTest, public ::testing::WithParamInterface<bool> { @@ -447,4 +535,70 @@ StopMirroring(); } +// Tests for which a target delay is set in the feature +// kCastMirroringPlayoutDelayMs. +class CastMirroringServiceHostBrowserTestTargetDelay + : public CastMirroringServiceHostBrowserTest { + public: + // A value to set for playout delay which is different than the default value + // used by casting code. + const int kFeaturePlayoutDelay500ms = 500; + + CastMirroringServiceHostBrowserTestTargetDelay() { + feature_list_.Reset(); + base::FieldTrialParams feature_params; + feature_params[media_router::kCastMirroringPlayoutDelayMs.name] = + base::NumberToString(kFeaturePlayoutDelay500ms); + feature_list_.InitAndEnableFeatureWithParameters( + media_router::kCastMirroringPlayoutDelay, feature_params); + } + + CastMirroringServiceHostBrowserTestTargetDelay( + const CastMirroringServiceHostBrowserTestTargetDelay&) = delete; + CastMirroringServiceHostBrowserTestTargetDelay& operator=( + const CastMirroringServiceHostBrowserTestTargetDelay&) = delete; + + ~CastMirroringServiceHostBrowserTestTargetDelay() override = default; + + void VerifyEnabledFeatureParam() { + ASSERT_TRUE( + base::FeatureList::IsEnabled(media_router::kCastMirroringPlayoutDelay)); + + ASSERT_EQ(media_router::kCastMirroringPlayoutDelayMs.Get(), + kFeaturePlayoutDelay500ms); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Test that the target playout delay set in the kCastMirroringPlayoutDelay +// feature param is used when starting the session, if there is no preset delay +// from a media source. +IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTestTargetDelay, + TabMirrorWithPlayoutDelay) { + VerifyEnabledFeatureParam(); + StartTabMirroringWithTargetPlayoutDelay( + /* media_source_delay = */ base::Milliseconds(0), + /*feature_delay = */ base::Milliseconds(kFeaturePlayoutDelay500ms)); + GetVideoCaptureHost(); + StartVideoCapturing(); + RequestRefreshFrame(); + StopMirroring(); +} + +// Test that a playout delay set by a media source overrides a delay set in the +// kCastMirroringPlayoutDelay feature param. +IN_PROC_BROWSER_TEST_F(CastMirroringServiceHostBrowserTestTargetDelay, + TabMirrorWithPresetPlayoutDelay) { + VerifyEnabledFeatureParam(); + StartTabMirroringWithTargetPlayoutDelay( + /* media_source_delay = */ base::Milliseconds(200), + /* feature_delay = */ base::Milliseconds(kFeaturePlayoutDelay500ms)); + GetVideoCaptureHost(); + StartVideoCapturing(); + RequestRefreshFrame(); + StopMirroring(); +} + } // namespace mirroring
diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browser/media/router/media_router_feature.cc index c75e3ca..5dc6b93 100644 --- a/chrome/browser/media/router/media_router_feature.cc +++ b/chrome/browser/media/router/media_router_feature.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/base64.h" +#include "base/command_line.h" #include "base/containers/flat_map.h" #include "base/feature_list.h" #include "base/no_destructor.h" @@ -21,6 +22,7 @@ #include "components/prefs/pref_service.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_context.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "crypto/random.h" #include "media/base/media_switches.h" @@ -64,6 +66,11 @@ BASE_FEATURE(kCastDialogStopButton, "CastDialogStopButton", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kCastMirroringPlayoutDelay, + "CastMirroringPlayoutDelay", + base::FEATURE_DISABLED_BY_DEFAULT); +const base::FeatureParam<int> kCastMirroringPlayoutDelayMs{ + &kCastMirroringPlayoutDelay, "cast_mirroring_playout_delay_ms", -1}; #if BUILDFLAG(IS_CHROMEOS) BASE_FEATURE(kGlobalMediaControlsCastStartStop, "GlobalMediaControlsCastStartStop", @@ -88,6 +95,13 @@ return *stored_pref_values; } + +#if !BUILDFLAG(IS_ANDROID) +// TODO(mfoltz): Add full implementation for validating playout delay value. +bool IsValidMirroringPlayoutDelayMs(int delay_ms) { + return delay_ms <= 1000 && delay_ms >= 1; +} +#endif // !BUILDFLAG(IS_ANDROID) } // namespace void ClearMediaRouterStoredPrefsForTesting() { @@ -186,6 +200,32 @@ MediaRouterEnabled(context); } +absl::optional<base::TimeDelta> GetCastMirroringPlayoutDelay() { + absl::optional<base::TimeDelta> target_playout_delay; + + // First see if there is a command line switch for mirroring playout delay. + // Otherwise, check the relevant feature. + const base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + if (cl->HasSwitch(switches::kCastMirroringTargetPlayoutDelay)) { + int switch_playout_delay = 0; + if (base::StringToInt( + cl->GetSwitchValueASCII(switches::kCastMirroringTargetPlayoutDelay), + &switch_playout_delay) && + IsValidMirroringPlayoutDelayMs(switch_playout_delay)) { + target_playout_delay = base::Milliseconds(switch_playout_delay); + } + } + + if (!target_playout_delay.has_value() && + base::FeatureList::IsEnabled(kCastMirroringPlayoutDelay) && + IsValidMirroringPlayoutDelayMs(kCastMirroringPlayoutDelayMs.Get())) { + target_playout_delay = + base::Milliseconds(kCastMirroringPlayoutDelayMs.Get()); + } + + return target_playout_delay; +} + #endif // !BUILDFLAG(IS_ANDROID) } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_feature.h b/chrome/browser/media/router/media_router_feature.h index c2f154b7..9e859fb 100644 --- a/chrome/browser/media/router/media_router_feature.h +++ b/chrome/browser/media/router/media_router_feature.h
@@ -6,6 +6,8 @@ #define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_FEATURE_H_ #include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" +#include "base/time/time.h" #include "build/build_config.h" class PrefRegistrySimple; @@ -69,6 +71,11 @@ // dialog instead of the entire sink button being a stop button. BASE_DECLARE_FEATURE(kCastDialogStopButton); +// If enabled, mirroring sessions use the playout delay specified by +// `kCastMirroringPlayoutDelayMs`. +BASE_DECLARE_FEATURE(kCastMirroringPlayoutDelay); +extern const base::FeatureParam<int> kCastMirroringPlayoutDelayMs; + // Registers |kMediaRouterCastAllowAllIPs| with local state pref |registry|. void RegisterLocalStatePrefs(PrefRegistrySimple* registry); @@ -91,6 +98,10 @@ // Returns true if global media controls are used to start and stop casting and // Media Router is enabled for |context|. bool GlobalMediaControlsCastStartStopEnabled(content::BrowserContext* context); + +// Returns the optional value to use for mirroring playout delay from the +// relevant command line flag or feature, if any are set. +absl::optional<base::TimeDelta> GetCastMirroringPlayoutDelay(); #endif // !BUILDFLAG(IS_ANDROID) } // namespace media_router
diff --git a/chrome/browser/media/router/media_router_feature_unittest.cc b/chrome/browser/media/router/media_router_feature_unittest.cc index d091010..c81ac50 100644 --- a/chrome/browser/media/router/media_router_feature_unittest.cc +++ b/chrome/browser/media/router/media_router_feature_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/test/scoped_feature_list.h" +#include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/common/pref_names.h" @@ -16,6 +17,7 @@ #include "components/prefs/testing_pref_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/browser_task_environment.h" +#include "media/base/media_switches.h" #include "testing/gtest/include/gtest/gtest.h" namespace media_router { @@ -51,6 +53,53 @@ EXPECT_EQ(token, GetReceiverIdHashToken(pref_service.get())); } +TEST(MediaRouterFeatureTest, GetCastMirroringPlayoutDelay) { + base::test::ScopedFeatureList feature_list; + base::FieldTrialParams feature_params; + feature_params[kCastMirroringPlayoutDelayMs.name] = "100"; + feature_list.InitAndEnableFeatureWithParameters(kCastMirroringPlayoutDelay, + feature_params); + EXPECT_TRUE(GetCastMirroringPlayoutDelay().has_value()); + EXPECT_EQ(GetCastMirroringPlayoutDelay().value(), base::Milliseconds(100)); + + // Incorrect values are ignored. + feature_list.Reset(); + feature_params[kCastMirroringPlayoutDelayMs.name] = "0"; + feature_list.InitAndEnableFeatureWithParameters(kCastMirroringPlayoutDelay, + feature_params); + EXPECT_FALSE(GetCastMirroringPlayoutDelay().has_value()); + + feature_list.Reset(); + feature_params[kCastMirroringPlayoutDelayMs.name] = "2000"; + feature_list.InitAndEnableFeatureWithParameters(kCastMirroringPlayoutDelay, + feature_params); + EXPECT_FALSE(GetCastMirroringPlayoutDelay().has_value()); +} + +TEST(MediaRouterFeatureTest, GetCastMirroringPlayoutDelayCommandLine) { + base::test::ScopedFeatureList feature_list; + // Test that an invalid switch is not returned. + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + command_line->AppendSwitchASCII(switches::kCastMirroringTargetPlayoutDelay, + "foo"); + EXPECT_FALSE(GetCastMirroringPlayoutDelay().has_value()); + + base::TimeDelta expected_delay = base::Milliseconds(200); + // Test that valid values are passed. + command_line->AppendSwitchASCII(switches::kCastMirroringTargetPlayoutDelay, + "200"); + EXPECT_EQ(GetCastMirroringPlayoutDelay().value(), expected_delay); + + // Test that command line takes precedence over feature. + base::FieldTrialParams feature_params; + feature_params[kCastMirroringPlayoutDelayMs.name] = "500"; + feature_list.InitAndEnableFeatureWithParameters(kCastMirroringPlayoutDelay, + feature_params); + ASSERT_NE(base::Milliseconds(kCastMirroringPlayoutDelayMs.Get()), + expected_delay); + EXPECT_EQ(GetCastMirroringPlayoutDelay().value(), base::Milliseconds(200)); +} + class MediaRouterEnabledTest : public ::testing::Test { public: MediaRouterEnabledTest() = default;
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.cc b/chrome/browser/media/router/providers/cast/mirroring_activity.cc index 91a9e35..0e41fab 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
@@ -607,8 +607,6 @@ channel_receiver_.Bind(channel_remote.InitWithNewPipeAndPassReceiver()); should_fetch_stats_on_start_ = enable_rtcp_reporting; - const absl::optional<base::TimeDelta> target_playout_delay = - GetTargetPlayoutDelay(cast_source->target_playout_delay()); // If this fails, it's probably because CreateMojoBindings() hasn't been // called. @@ -620,7 +618,8 @@ SessionParameters::New( session_type, cast_data_.ip_endpoint.address(), cast_data_.model_name, sink_.sink().name(), destination_id, - message_handler_->source_id(), target_playout_delay, + message_handler_->source_id(), + cast_source->target_playout_delay(), route().media_source().IsRemotePlaybackSource(), ShouldForceLetterboxing(cast_data_.model_name), enable_rtcp_reporting), @@ -716,24 +715,6 @@ debugger_->OnMirroringStats(json_stats.Clone()); } -absl::optional<base::TimeDelta> MirroringActivity::GetTargetPlayoutDelay( - const absl::optional<base::TimeDelta>& source_playout_delay) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_); - absl::optional<base::TimeDelta> default_target_playout_delay = - source_playout_delay; - - const base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); - if (cl->HasSwitch(switches::kCastMirroringTargetPlayoutDelay)) { - int switch_playout_delay = 0; - if (base::StringToInt( - cl->GetSwitchValueASCII(switches::kCastMirroringTargetPlayoutDelay), - &switch_playout_delay)) { - default_target_playout_delay = base::Milliseconds(switch_playout_delay); - } - } - return default_target_playout_delay; -} - void MirroringActivity::Play() { DCHECK_CALLED_ON_VALID_SEQUENCE(io_sequence_checker_); if (host_) {
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.h b/chrome/browser/media/router/providers/cast/mirroring_activity.h index dcfea05..ca6b3a4 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity.h +++ b/chrome/browser/media/router/providers/cast/mirroring_activity.h
@@ -130,7 +130,6 @@ FRIEND_TEST_ALL_PREFIXES(MirroringActivityTest, Pause); FRIEND_TEST_ALL_PREFIXES(MirroringActivityTest, Play); FRIEND_TEST_ALL_PREFIXES(MirroringActivityTest, OnRemotingStateChanged); - FRIEND_TEST_ALL_PREFIXES(MirroringActivityTest, GetTargetPlayoutDelay); FRIEND_TEST_ALL_PREFIXES(MirroringActivityTest, MultipleMediaControllersNotified); @@ -170,11 +169,6 @@ void FetchMirroringStats(); void OnMirroringStats(base::Value json_stats); - // Checks if we should override the target playout delay if the - // kCastMirroringTargetPlayoutDelay switch has a value. - absl::optional<base::TimeDelta> GetTargetPlayoutDelay( - const absl::optional<base::TimeDelta>& source_playout_delay); - std::unique_ptr<mirroring::MirroringServiceHost> host_; // Sends Cast messages from the mirroring receiver to the mirroring service.
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc index 7b942b0..b2695d8 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc
@@ -699,38 +699,6 @@ testing::Mock::VerifyAndClearExpectations(&media_status_observer); } -TEST_F(MirroringActivityTest, GetTargetPlayoutDelay) { - MakeActivity(); - - // Expect no command line switch will return the same value. - const base::TimeDelta default_playout_delay = base::Milliseconds(400); - EXPECT_EQ(activity_->GetTargetPlayoutDelay(default_playout_delay).value(), - default_playout_delay); - - // Expect no command line switch and a nullopt will return a nullopt. - EXPECT_EQ(activity_->GetTargetPlayoutDelay(absl::nullopt), absl::nullopt); - - // Test that an invalid switch (alpha-numeric string) will return the - // parameter value. - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII(switches::kCastMirroringTargetPlayoutDelay, - "foo"); - EXPECT_EQ(activity_->GetTargetPlayoutDelay(default_playout_delay).value(), - default_playout_delay); - - // Test that a valid switch will override the target playout delay. - const base::TimeDelta switch_playout_delay = base::Milliseconds(200); - command_line->AppendSwitchASCII( - switches::kCastMirroringTargetPlayoutDelay, - base::NumberToString(switch_playout_delay.InMilliseconds())); - EXPECT_EQ(activity_->GetTargetPlayoutDelay(switch_playout_delay).value(), - switch_playout_delay); - - // Test that returned value is the switch even with nullopt. - EXPECT_EQ(activity_->GetTargetPlayoutDelay(absl::nullopt).value(), - switch_playout_delay); -} - TEST_F(MirroringActivityTest, MultipleMediaControllersNotified) { MakeActivity();
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_factory.cc b/chrome/browser/media_galleries/media_galleries_preferences_factory.cc index 4a9ec696..2004a5b 100644 --- a/chrome/browser/media_galleries/media_galleries_preferences_factory.cc +++ b/chrome/browser/media_galleries/media_galleries_preferences_factory.cc
@@ -34,9 +34,11 @@ MediaGalleriesPreferencesFactory::~MediaGalleriesPreferencesFactory() = default; -KeyedService* MediaGalleriesPreferencesFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +MediaGalleriesPreferencesFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const { - return new MediaGalleriesPreferences(static_cast<Profile*>(profile)); + return std::make_unique<MediaGalleriesPreferences>( + static_cast<Profile*>(profile)); } void MediaGalleriesPreferencesFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_factory.h b/chrome/browser/media_galleries/media_galleries_preferences_factory.h index 43ec607..1348904 100644 --- a/chrome/browser/media_galleries/media_galleries_preferences_factory.h +++ b/chrome/browser/media_galleries/media_galleries_preferences_factory.h
@@ -33,7 +33,7 @@ ~MediaGalleriesPreferencesFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/metrics/structured/ash_structured_metrics_recorder_browsertest.cc b/chrome/browser/metrics/structured/ash_structured_metrics_recorder_browsertest.cc index 5ba4fb1..5ad3c41 100644 --- a/chrome/browser/metrics/structured/ash_structured_metrics_recorder_browsertest.cc +++ b/chrome/browser/metrics/structured/ash_structured_metrics_recorder_browsertest.cc
@@ -62,18 +62,6 @@ ->SetOnEventsRecordClosure(delegate); } - void AddProfile() { - structured_metrics_mixin_.GetTestStructuredMetricsProvider() - ->AddProfilePath(base::FilePath(FILE_PATH_LITERAL("structured_metrics")) - .Append(FILE_PATH_LITERAL("user_keys"))); - } - - void WaitUntilInit() { - // Wait for keys to be initialized and state to be propagated async. - structured_metrics_mixin_.GetTestStructuredMetricsProvider() - ->WaitUntilReady(); - } - protected: StructuredMetricsMixin structured_metrics_mixin_{&mixin_host_}; @@ -84,11 +72,6 @@ IN_PROC_BROWSER_TEST_F(AshStructuredMetricsRecorderTest, SendValidEventAndSuccessfullyRecords) { - // Add a profile otherwise event will not be hashed. Then wait for - // initialization to occur. - AddProfile(); - WaitUntilInit(); - events::v2::test_project_one::TestEventOne test_event; test_event.SetTestMetricOne("hash").SetTestMetricTwo(1);
diff --git a/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc b/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc index dc42e24..5586605 100644 --- a/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc +++ b/chrome/browser/metrics/structured/chrome_structured_metrics_recorder.cc
@@ -7,18 +7,16 @@ #include <stdint.h> #include "base/no_destructor.h" +#include "base/task/sequenced_task_runner.h" +#include "components/metrics/structured/histogram_util.h" #include "components/metrics/structured/recorder.h" #include "components/metrics/structured/structured_metrics_features.h" -#include "components/metrics_services_manager/metrics_services_manager.h" #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/browser_process.h" // nogncheck #include "chrome/browser/metrics/structured/ash_structured_metrics_recorder.h" // nogncheck #include "chrome/browser/metrics/structured/cros_events_processor.h" // nogncheck -#include "chrome/browser/metrics/structured/key_data_provider_ash.h" // nogncheck #include "chrome/browser/metrics/structured/metadata_processor_ash.h" // nogncheck -#include "components/metrics/structured/structured_metrics_recorder.h" // nogncheck -#include "components/metrics/structured/structured_metrics_service.h" // nogncheck #elif BUILDFLAG(IS_CHROMEOS_LACROS) #include "base/task/current_thread.h" #include "chrome/browser/metrics/structured/lacros_structured_metrics_recorder.h" // nogncheck @@ -83,12 +81,6 @@ cros_event::kResetCounterPath)); } - // Initialize the key data provider. - g_browser_process->GetMetricsServicesManager() - ->GetStructuredMetricsService() - ->recorder() - ->InitializeKeyDataProvider(std::make_unique<KeyDataProviderAsh>()); - Recorder::GetInstance()->AddEventsProcessor( std::make_unique<MetadataProcessorAsh>());
diff --git a/chrome/browser/metrics/structured/key_data_provider_ash.cc b/chrome/browser/metrics/structured/key_data_provider_ash.cc deleted file mode 100644 index 0f21743..0000000 --- a/chrome/browser/metrics/structured/key_data_provider_ash.cc +++ /dev/null
@@ -1,84 +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. - -#include "chrome/browser/metrics/structured/key_data_provider_ash.h" - -namespace metrics::structured { -namespace { -// The delay period for the PersistentProto. -constexpr int kSaveDelayMs = 1000; - -// The path used to store per-profile keys. Relative to the user's -// cryptohome. This file is created by chromium. -constexpr char kProfileKeyPath[] = "structured_metrics/keys"; - -// The path used to store per-device keys. This file is created by tmpfiles.d -// on start and has its permissions and ownership set such that it is writable -// by chronos. -constexpr char kDeviceKeyPath[] = "/var/lib/metrics/structured/chromium/keys"; - -} // namespace - -KeyDataProviderAsh::KeyDataProviderAsh() - : KeyDataProviderAsh(base::FilePath(kDeviceKeyPath), kSaveDelayMs) {} - -KeyDataProviderAsh::KeyDataProviderAsh(const base::FilePath& device_key_path, - int write_delay_ms) - : device_key_path_(device_key_path), write_delay_ms_(write_delay_ms) {} - -KeyDataProviderAsh::~KeyDataProviderAsh() = default; - -void KeyDataProviderAsh::InitializeDeviceKey(base::OnceClosure callback) { - if (HasDeviceKey()) { - return; - } - - device_key_ = std::make_unique<KeyData>(device_key_path_, - base::Milliseconds(write_delay_ms_), - std::move(callback)); -} - -void KeyDataProviderAsh::InitializeProfileKey( - const base::FilePath& profile_path, - base::OnceClosure callback) { - // Only the primary user's keys should be loaded. If there is already is a - // profile key, no-op. - if (HasProfileKey()) { - return; - } - - profile_key_ = std::make_unique<KeyData>(profile_path.Append(kProfileKeyPath), - base::Milliseconds(write_delay_ms_), - std::move(callback)); -} - -KeyData* KeyDataProviderAsh::GetDeviceKeyData() { - DCHECK(HasDeviceKey()); - return device_key_.get(); -} - -KeyData* KeyDataProviderAsh::GetProfileKeyData() { - DCHECK(HasProfileKey()); - return profile_key_.get(); -} - -void KeyDataProviderAsh::Purge() { - if (HasDeviceKey()) { - GetDeviceKeyData()->Purge(); - } - - if (HasProfileKey()) { - GetProfileKeyData()->Purge(); - } -} - -bool KeyDataProviderAsh::HasProfileKey() { - return profile_key_ != nullptr; -} - -bool KeyDataProviderAsh::HasDeviceKey() { - return profile_key_ != nullptr; -} - -} // namespace metrics::structured
diff --git a/chrome/browser/metrics/structured/key_data_provider_ash.h b/chrome/browser/metrics/structured/key_data_provider_ash.h deleted file mode 100644 index 97008e1a..0000000 --- a/chrome/browser/metrics/structured/key_data_provider_ash.h +++ /dev/null
@@ -1,44 +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. - -#ifndef CHROME_BROWSER_METRICS_STRUCTURED_KEY_DATA_PROVIDER_ASH_H_ -#define CHROME_BROWSER_METRICS_STRUCTURED_KEY_DATA_PROVIDER_ASH_H_ - -#include "components/metrics/structured/key_data_provider.h" - -namespace metrics::structured { - -// Implementation for Ash Chrome to provide keys to StructuredMetricsRecorder. -// -// Device keys are stored in a static path while profile keys are stored in the -// user's cryptohome partition. -// -// InitializeProfileKey should only be called once for the primary user. All -// subsequent calls will no-op. -class KeyDataProviderAsh : public KeyDataProvider { - public: - KeyDataProviderAsh(const base::FilePath& device_key_path, int write_delay_ms); - KeyDataProviderAsh(); - ~KeyDataProviderAsh() override; - - // KeyDataProvider: - void InitializeDeviceKey(base::OnceClosure callback) override; - void InitializeProfileKey(const base::FilePath& profile_path, - base::OnceClosure callback) override; - KeyData* GetDeviceKeyData() override; - KeyData* GetProfileKeyData() override; - void Purge() override; - bool HasProfileKey() override; - bool HasDeviceKey() override; - - private: - const base::FilePath device_key_path_; - int write_delay_ms_; - - std::unique_ptr<KeyData> device_key_; - std::unique_ptr<KeyData> profile_key_; -}; -} // namespace metrics::structured - -#endif // CHROME_BROWSER_METRICS_STRUCTURED_KEY_DATA_PROVIDER_ASH_H_
diff --git a/chrome/browser/metrics/structured/structured_metrics_key_events_observer.h b/chrome/browser/metrics/structured/structured_metrics_key_events_observer.h index e7efa953..601401c8 100644 --- a/chrome/browser/metrics/structured/structured_metrics_key_events_observer.h +++ b/chrome/browser/metrics/structured/structured_metrics_key_events_observer.h
@@ -39,10 +39,14 @@ void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; private: - raw_ptr<user_manager::UserManager, ExperimentalAsh> user_manager_; - raw_ptr<ash::SessionTerminationManager, ExperimentalAsh> + raw_ptr<user_manager::UserManager, LeakedDanglingUntriaged | ExperimentalAsh> + user_manager_; + raw_ptr<ash::SessionTerminationManager, + LeakedDanglingUntriaged | ExperimentalAsh> session_termination_manager_; - raw_ptr<chromeos::PowerManagerClient, ExperimentalAsh> power_manager_client_; + raw_ptr<chromeos::PowerManagerClient, + LeakedDanglingUntriaged | ExperimentalAsh> + power_manager_client_; }; } // namespace metrics::structured
diff --git a/chrome/browser/metrics/structured/test/structured_metrics_mixin.cc b/chrome/browser/metrics/structured/test/structured_metrics_mixin.cc index f787e057..edb95ff1 100644 --- a/chrome/browser/metrics/structured/test/structured_metrics_mixin.cc +++ b/chrome/browser/metrics/structured/test/structured_metrics_mixin.cc
@@ -9,7 +9,10 @@ StructuredMetricsMixin::StructuredMetricsMixin( InProcessBrowserTestMixinHost* host) - : InProcessBrowserTestMixin(host) {} + : InProcessBrowserTestMixin(host) { + test_structured_metrics_provider_ = + std::make_unique<TestStructuredMetricsProvider>(); +} StructuredMetricsMixin::~StructuredMetricsMixin() = default; @@ -17,11 +20,6 @@ EnableMetricsRecordingOnlyForTesting(command_line); } -void StructuredMetricsMixin::SetUpOnMainThread() { - test_structured_metrics_provider_ = - std::make_unique<TestStructuredMetricsProvider>(); -} - TestStructuredMetricsProvider* StructuredMetricsMixin::GetTestStructuredMetricsProvider() { return test_structured_metrics_provider_.get();
diff --git a/chrome/browser/metrics/structured/test/structured_metrics_mixin.h b/chrome/browser/metrics/structured/test/structured_metrics_mixin.h index 776ad7d7..70e8a823 100644 --- a/chrome/browser/metrics/structured/test/structured_metrics_mixin.h +++ b/chrome/browser/metrics/structured/test/structured_metrics_mixin.h
@@ -30,7 +30,6 @@ // InProcessBrowserTestMixin: void SetUpCommandLine(base::CommandLine* command_line) override; - void SetUpOnMainThread() override; private: std::unique_ptr<TestStructuredMetricsProvider>
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_metrics_document_data.cc b/chrome/browser/navigation_predictor/navigation_predictor_metrics_document_data.cc index 9bb5e23..6ac78de 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_metrics_document_data.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_metrics_document_data.cc
@@ -220,6 +220,11 @@ }; auto* ukm_recorder = ukm::UkmRecorder::Get(); + auto get_exponential_bucket_for_signed_values = [](int64_t sample, + double bucket_spacing) { + return ukm::GetExponentialBucketMin(std::abs(sample), bucket_spacing) * + (sample >= 0 ? 1 : -1); + }; for (const auto& [anchor_index, user_interaction] : user_interactions_) { ukm::builders::NavigationPredictorUserInteractions builder(ukm_source_id); @@ -239,9 +244,9 @@ get_max_time_ms(user_interaction.max_hover_dwell_time, user_interaction.last_navigation_start_to_pointer_over), 1.3)); - builder.SetMouseVelocity(ukm::GetExponentialBucketMin( + builder.SetMouseVelocity(get_exponential_bucket_for_signed_values( user_interaction.mouse_velocity.value_or(0.0), 1.3)); - builder.SetMouseAcceleration(ukm::GetExponentialBucketMin( + builder.SetMouseAcceleration(get_exponential_bucket_for_signed_values( user_interaction.mouse_acceleration.value_or(0.0), 1.3)); builder.Record(ukm_recorder); }
diff --git a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc index ac0dac34..b0ac720 100644 --- a/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc +++ b/chrome/browser/navigation_predictor/navigation_predictor_unittest.cc
@@ -815,7 +815,7 @@ const int navigation_start_to_pointer_over_0 = 140; const int hover_dwell_time_0 = 60; const double mouse_velocity = 50.0; - const double mouse_acceleration = 10.0; + const double mouse_acceleration = -10.0; ReportAnchorElementPointerOver( predictor_service.get(), anchor_id_0, base::Milliseconds(navigation_start_to_pointer_over_0)); @@ -874,9 +874,9 @@ get_metric(i, UkmEntry::kMaxHoverDwellTimeMsName)); EXPECT_EQ(ukm::GetExponentialBucketMin(1, 1.3), get_metric(i, UkmEntry::kPointerHoveringOverCountName)); - EXPECT_EQ(ukm::GetExponentialBucketMin(mouse_velocity, 1.3), + EXPECT_EQ(/*get_exponential_bucket_for_signed_values(50)=*/40, get_metric(i, UkmEntry::kMouseVelocityName)); - EXPECT_EQ(ukm::GetExponentialBucketMin(mouse_acceleration, 1.3), + EXPECT_EQ(/*get_exponential_bucket_for_signed_values(-10)=*/-9, get_metric(i, UkmEntry::kMouseAccelerationName)); break;
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_storage_impl_unittest.cc b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_storage_impl_unittest.cc index 230950c6..e2d48ed0 100644 --- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_storage_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_storage_impl_unittest.cc
@@ -205,7 +205,7 @@ std::unique_ptr<TestingPrefServiceSimple> pref_service_; std::map<std::string, nearbyshare::proto::PublicCertificate> db_entries_; raw_ptr<leveldb_proto::test::FakeDB<nearbyshare::proto::PublicCertificate>, - ExperimentalAsh> + DanglingUntriaged | ExperimentalAsh> db_; std::unique_ptr<NearbyShareCertificateStorage> cert_store_; std::vector<nearbyshare::proto::PublicCertificate> public_certificates_;
diff --git a/chrome/browser/nearby_sharing/instantmessaging/token_fetcher.h b/chrome/browser/nearby_sharing/instantmessaging/token_fetcher.h index 3a01c6b..e0a9cc4e 100644 --- a/chrome/browser/nearby_sharing/instantmessaging/token_fetcher.h +++ b/chrome/browser/nearby_sharing/instantmessaging/token_fetcher.h
@@ -33,7 +33,8 @@ GoogleServiceAuthError error, signin::AccessTokenInfo access_token_info); - raw_ptr<signin::IdentityManager, ExperimentalAsh> identity_manager_; + raw_ptr<signin::IdentityManager, LeakedDanglingUntriaged | ExperimentalAsh> + identity_manager_; std::unique_ptr<signin::AccessTokenFetcher> token_fetcher_; base::WeakPtrFactory<TokenFetcher> weak_ptr_factory_{this};
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc index 4513551..4f42e1a61 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc
@@ -102,7 +102,8 @@ NearbySharingServiceFactory::~NearbySharingServiceFactory() = default; -KeyedService* NearbySharingServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +NearbySharingServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { if (!IsNearbyShareSupportedForBrowserContext(context)) { return nullptr; @@ -124,7 +125,7 @@ NS_LOG(VERBOSE) << __func__ << ": creating NearbySharingService for primary profile"; - return new NearbySharingServiceImpl( + return std::make_unique<NearbySharingServiceImpl>( pref_service, notification_display_service, profile, std::move(nearby_connections_manager), process_manager, std::make_unique<PowerClientChromeos>(),
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.h b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.h index b46f433..5aeaf53 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.h +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.h
@@ -48,7 +48,7 @@ ~NearbySharingServiceFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/new_tab_page/modules/drive/drive_service.cc b/chrome/browser/new_tab_page/modules/drive/drive_service.cc index b9aa8d7..5327309 100644 --- a/chrome/browser/new_tab_page/modules/drive/drive_service.cc +++ b/chrome/browser/new_tab_page/modules/drive/drive_service.cc
@@ -279,8 +279,7 @@ void DriveService::GetDriveFilesInternal() { // Bail if module is still dismissed. - if (!base::FeatureList::IsEnabled(ntp_features::kNtpModulesRedesigned) && - !pref_service_->GetTime(kLastDismissedTimePrefName).is_null() && + if (!pref_service_->GetTime(kLastDismissedTimePrefName).is_null() && base::Time::Now() - pref_service_->GetTime(kLastDismissedTimePrefName) < kDismissDuration) { for (auto& callback : callbacks_) {
diff --git a/chrome/browser/new_tab_page/modules/drive/drive_service_factory.cc b/chrome/browser/new_tab_page/modules/drive/drive_service_factory.cc index 1e49bc0..c04be9f 100644 --- a/chrome/browser/new_tab_page/modules/drive/drive_service_factory.cc +++ b/chrome/browser/new_tab_page/modules/drive/drive_service_factory.cc
@@ -40,12 +40,13 @@ DriveServiceFactory::~DriveServiceFactory() = default; -KeyedService* DriveServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +DriveServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { auto url_loader_factory = context->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess(); auto* profile = Profile::FromBrowserContext(context); - return new DriveService( + return std::make_unique<DriveService>( url_loader_factory, IdentityManagerFactory::GetForProfile(profile), segmentation_platform::SegmentationPlatformServiceFactory::GetForProfile( profile),
diff --git a/chrome/browser/new_tab_page/modules/drive/drive_service_factory.h b/chrome/browser/new_tab_page/modules/drive/drive_service_factory.h index 5808903..565fed4f 100644 --- a/chrome/browser/new_tab_page/modules/drive/drive_service_factory.h +++ b/chrome/browser/new_tab_page/modules/drive/drive_service_factory.h
@@ -23,7 +23,7 @@ ~DriveServiceFactory() override; // Uses BrowserContextKeyedServiceFactory to build a DriveService. - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/new_tab_page/modules/drive/drive_service_unittest.cc b/chrome/browser/new_tab_page/modules/drive/drive_service_unittest.cc index dc2a112..0c4148a 100644 --- a/chrome/browser/new_tab_page/modules/drive/drive_service_unittest.cc +++ b/chrome/browser/new_tab_page/modules/drive/drive_service_unittest.cc
@@ -681,65 +681,3 @@ EXPECT_FALSE(fake_documents.empty()); } - -class DriveServiceModulesRedesignedTest : public DriveServiceTest { - public: - DriveServiceModulesRedesignedTest() { - features_.InitAndEnableFeature(ntp_features::kNtpModulesRedesigned); - } - - private: - base::test::ScopedFeatureList features_; -}; - -TEST_F(DriveServiceModulesRedesignedTest, IgnoresDismiss) { - auto quit_closure = task_environment_.QuitClosure(); - bool passed_data = false; - base::MockCallback<DriveService::GetFilesCallback> callback; - EXPECT_CALL(callback, Run(testing::_)) - .Times(1) - .WillOnce( - testing::Invoke([&](std::vector<drive::mojom::FilePtr> suggestions) { - passed_data = !suggestions.empty(); - quit_closure.Run(); - })); - identity_test_env.SetAutomaticIssueOfAccessTokens(/*grant=*/true); - test_url_loader_factory_.AddResponse( - "https://appsitemsuggest-pa.googleapis.com/v1/items", - R"( - { - "item": [ - { - "itemId":"123", - "url":"https://google.com/bar", - "driveItem": { - "title": "Bar", - "mimeType": "application/vnd.google-apps.document" - }, - "justification": { - "unstructuredJustificationDescription": { - "textSegment": [ - { - "text": "Foo " - }, - { - "text": "bar foo bar" - } - ] - } - } - }, - { - "driveItem": { - } - } - ] - } - )"); - - service_->DismissModule(); - service_->GetDriveFiles(callback.Get()); - task_environment_.RunUntilQuit(); - - EXPECT_TRUE(passed_data); -}
diff --git a/chrome/browser/new_tab_page/modules/new_tab_page_modules_interactive_uitest.cc b/chrome/browser/new_tab_page/modules/new_tab_page_modules_interactive_uitest.cc index 46f10318..13abb1a99 100644 --- a/chrome/browser/new_tab_page/modules/new_tab_page_modules_interactive_uitest.cc +++ b/chrome/browser/new_tab_page/modules/new_tab_page_modules_interactive_uitest.cc
@@ -313,6 +313,7 @@ "ntp-module-wrapper", "ntp-history-clusters-redesigned", "history-clusters-header-v2", + "ntp-module-header-v2", "cr-action-menu", "dialog"}; const DeepQuery kHistoryClustersHideButton = { @@ -321,6 +322,7 @@ "ntp-module-wrapper", "ntp-history-clusters-redesigned", "history-clusters-header-v2", + "ntp-module-header-v2", "#dismiss"}; RunTestSequence( @@ -373,6 +375,7 @@ "ntp-module-wrapper", "ntp-history-clusters-redesigned", "history-clusters-header-v2", + "ntp-module-header-v2", "cr-action-menu", "dialog"}; const DeepQuery kHistoryClustersDoneButton = { @@ -381,6 +384,7 @@ "ntp-module-wrapper", "ntp-history-clusters-redesigned", "history-clusters-header-v2", + "ntp-module-header-v2", "#done"}; RunTestSequence(
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index b8e2cf4d..a0e7945f 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -20,7 +20,6 @@ #include "build/chromeos_buildflags.h" #include "chrome/browser/browsing_data/browsing_data_lifetime_policy_handler.h" #include "chrome/browser/enterprise/connectors/device_trust/prefs.h" -#include "chrome/browser/enterprise/idle/idle_timeout_policy_handler.h" #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_policy_handler.h" #include "chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler.h" #include "chrome/browser/media/webrtc/capture_policy_utils.h" @@ -220,6 +219,11 @@ #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_ANDROID) +#include "components/enterprise/idle/idle_timeout_policy_handler.h" +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_ANDROID) #include "chrome/browser/privacy_sandbox/privacy_sandbox_policy_handler.h" #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) ||
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index e8654d5..c48f139 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -339,12 +339,6 @@ */ public static final String FLAGS_CACHED_GRID_TAB_SWITCHER_ENABLED = "grid_tab_switcher_enabled"; /** - * Whether warming up network service is enabled. - * Default value is false. - */ - public static final String FLAGS_CACHED_NETWORK_SERVICE_WARM_UP_ENABLED = - "network_service_warm_up_enabled"; - /** * Whether or not the start surface is enabled. * Default value is false. */
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java index 58d88e69..58d23b33 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/DeprecatedChromePreferenceKeys.java
@@ -118,6 +118,7 @@ "labeled_bottom_toolbar_enabled", "last_shared_class_name", "last_shared_package_name", + "network_service_warm_up_enabled", "night_mode_available", "night_mode_cct_available", "night_mode_default_to_light",
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java index a24a0a8..d0fb19d 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
@@ -60,7 +60,6 @@ ChromePreferenceKeys.FLAGS_CACHED_ADAPTIVE_TOOLBAR_ENABLED, ChromePreferenceKeys.FLAGS_CACHED_COMMAND_LINE_ON_NON_ROOTED_ENABLED, ChromePreferenceKeys.FLAGS_CACHED_GRID_TAB_SWITCHER_ENABLED, - ChromePreferenceKeys.FLAGS_CACHED_NETWORK_SERVICE_WARM_UP_ENABLED, ChromePreferenceKeys.FLAGS_CACHED_START_SURFACE_ENABLED, ChromePreferenceKeys.FLAGS_CACHED_TAB_GROUPS_ANDROID_ENABLED, ChromePreferenceKeys.FONT_USER_FONT_SCALE_FACTOR,
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index aa4b719..819ea8a1 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -165,10 +165,11 @@ const std::vector<uint32_t>& pages, uint32_t total_page_count) { std::vector<uint32_t> mapping(total_page_count, kInvalidPageIndex); - for (uint32_t page_number : pages) { + for (uint32_t page_index : pages) { // Make sure the page is in range. - if (page_number < total_page_count) - mapping[page_number] = page_number; + if (page_index < total_page_count) { + mapping[page_index] = page_index; + } } return mapping; } @@ -417,13 +418,13 @@ base::BindRepeating(&PrintJob::OnPdfPageConverted, this)); } -void PrintJob::OnPdfPageConverted(uint32_t page_number, +void PrintJob::OnPdfPageConverted(uint32_t page_index, float scale_factor, std::unique_ptr<MetafilePlayer> metafile) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(pdf_conversion_state_); - if (!document_ || !metafile || page_number == kInvalidPageIndex || - page_number >= pdf_page_mapping_.size()) { + if (!document_ || !metafile || page_index == kInvalidPageIndex || + page_index >= pdf_page_mapping_.size()) { // Be sure to live long enough. scoped_refptr<PrintJob> handle(this); pdf_conversion_state_.reset(); @@ -433,9 +434,9 @@ // Add the page to the document if it is one of the pages requested by the // user. If it is not, ignore it. - if (pdf_page_mapping_[page_number] != kInvalidPageIndex) { + if (pdf_page_mapping_[page_index] != kInvalidPageIndex) { // Update the rendered document. It will send notifications to the listener. - document_->SetPage(pdf_page_mapping_[page_number], std::move(metafile), + document_->SetPage(pdf_page_mapping_[page_index], std::move(metafile), scale_factor, pdf_conversion_state_->page_size(), pdf_conversion_state_->content_area()); }
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h index 4af8e6b..6f4d9ba 100644 --- a/chrome/browser/printing/print_job.h +++ b/chrome/browser/printing/print_job.h
@@ -238,7 +238,7 @@ const GURL& url); void OnPdfConversionStarted(uint32_t page_count); - void OnPdfPageConverted(uint32_t page_number, + void OnPdfPageConverted(uint32_t page_index, float scale_factor, std::unique_ptr<MetafilePlayer> metafile);
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc index 2d48682..e0a1d978 100644 --- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc +++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -26,9 +26,6 @@ #include "content/public/browser/child_process_launcher_utils.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/content_features.h" @@ -46,8 +43,6 @@ #include "content/public/browser/browser_child_process_host.h" #endif // BUILDFLAG(IS_MAC) -using content::RenderViewHost; -using content::RenderWidgetHost; using content::WebContents; namespace { @@ -57,18 +52,13 @@ } WebContents* FindFirstDevToolsContents() { - std::unique_ptr<content::RenderWidgetHostIterator> widgets( - RenderWidgetHost::GetRenderWidgetHosts()); - while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { - if (!widget->GetProcess()->IsInitializedAndNotDead()) - continue; - RenderViewHost* view_host = RenderViewHost::From(widget); - if (!view_host) - continue; - WebContents* contents = WebContents::FromRenderViewHost(view_host); - GURL url = contents->GetURL(); - if (url.SchemeIs(content::kChromeDevToolsScheme)) - return contents; + for (content::WebContents* web_contents : content::GetAllWebContents()) { + if (web_contents->GetURL().SchemeIs(content::kChromeDevToolsScheme) && + web_contents->GetPrimaryMainFrame() + ->GetProcess() + ->IsInitializedAndNotDead()) { + return web_contents; + } } return nullptr; }
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_row.html b/chrome/browser/resources/ash/settings/device_page/customize_button_row.html index fc21d25..93b6c4b 100644 --- a/chrome/browser/resources/ash/settings/device_page/customize_button_row.html +++ b/chrome/browser/resources/ash/settings/device_page/customize_button_row.html
@@ -67,7 +67,7 @@ </option> </template> <option id="keyCombination" value="[[keyCombinationOptionValue_]]"> - $i18n{keyCombinationOptionLabel} + [[keyCombinationLabel_]] </option> </select> </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts b/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts index a1035f05f..42613157 100644 --- a/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts +++ b/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts
@@ -23,11 +23,55 @@ import {cast} from '../assert_extras.js'; import {getTemplate} from './customize_button_row.html.js'; -import {ActionChoice, ButtonRemapping} from './input_device_settings_types.js'; +import {ActionChoice, ButtonRemapping, KeyEvent} from './input_device_settings_types.js'; const NO_REMAPPING_OPTION_LABEL = 'none'; const KEY_COMBINATION_OPTION_LABEL = 'key combination'; +/** + * Bit mask of modifiers. + * Ordering is according to UX, but values match EventFlags in + * ui/events/event_constants.h. + */ +enum Modifier { + NONE = 0, + CONTROL = 1 << 2, + SHIFT = 1 << 1, + ALT = 1 << 3, + META = 1 << 4, +} + +/** + * Map the modifier keys to the bit value. Currently the modifiers only + * contains the following four. + */ +const modifierBitMaskToString: Map<number, string> = new Map([ + [Modifier.CONTROL, 'ctrl'], + [Modifier.SHIFT, 'shift'], + [Modifier.ALT, 'alt'], + [Modifier.META, 'meta'], +]); + +function concateKeyString(firstStr: string, secondStr: string): string { + return firstStr.length === 0 ? secondStr : firstStr.concat(` + ${secondStr}`); +} + +/** + * Converts a keyEvent to a string representing all the modifiers and the vkey. + */ +function getKeyCombinationLabel(keyEvent: KeyEvent): string { + let combinationLabel = ''; + modifierBitMaskToString.forEach((modifierName: string, bitValue: number) => { + if ((keyEvent.modifiers & bitValue) !== 0) { + combinationLabel = concateKeyString(combinationLabel, modifierName); + } + }); + if (keyEvent.keyDisplay !== undefined && keyEvent.keyDisplay.length !== 0) { + combinationLabel = concateKeyString(combinationLabel, keyEvent.keyDisplay); + } + return combinationLabel; +} + const CustomizeButtonRowElementBase = I18nMixin(PolymerElement); export class CustomizeButtonRowElement extends CustomizeButtonRowElementBase { @@ -78,8 +122,12 @@ reflectToAttribute: true, }, + keyCombinationLabel_: { + type: String, + }, + /** - * The value of the "None" item. + * The value of the "None" item in dropdown menu. */ noRemappingOptionValue_: { type: String, @@ -88,7 +136,7 @@ }, /** - * The value of the "Key combination" item. + * The value of the "Key combination" item in dropdown menu. */ keyCombinationOptionValue_: { type: String, @@ -101,7 +149,7 @@ static get observers(): string[] { return [ 'onSettingsChanged(fakePref_.*)', - 'initializeCustomizeKey(buttonRemappingList, remappingIndex)', + 'initializeCustomizeKey(buttonRemappingList.*, remappingIndex)', ]; } @@ -113,6 +161,7 @@ private fakePref_: chrome.settingsPrivate.PrefObject; private noRemappingOptionValue_: string; private keyCombinationOptionValue_: string; + private keyCombinationLabel_: string; /** * Populate dropdown menu choices. @@ -133,26 +182,25 @@ } /** - * Initialize the button remapping content and set up fake pref. + * Populate the button remapping action according to the existing settings. */ - private initializeCustomizeKey(): void { - if (!this.buttonRemappingList || - !this.buttonRemappingList[this.remappingIndex]) { - return; - } - this.buttonRemapping_ = this.buttonRemappingList[this.remappingIndex]; - this.setUpButtonMapTargets_(); + private setUpRemappingActions_(): void { + const dropdown = cast( + this.shadowRoot!.querySelector('#remappingActionDropdown'), + HTMLSelectElement); + + // Set the dropdown option label to default 'Key combination'. + this.keyCombinationLabel_ = this.i18n('keyCombinationOptionLabel'); // For accelerator actions, the remappingAction.action value is number. // TODO(yyhyyh@): Add the case when remappingAction is none or Keyboard // events. - const action = this.buttonRemapping_.remappingAction!.action; + const action = this.buttonRemapping_.remappingAction?.action; + const keyEvent = this.buttonRemapping_.remappingAction?.keyEvent; if (action !== undefined && !isNaN(action)) { const originalAction = this.buttonRemapping_.remappingAction!.action!.toString(); - const dropdown = cast( - this.shadowRoot!.querySelector('#remappingActionDropdown'), - HTMLSelectElement); + // Initialize fakePref with the tablet settings mapping. this.set('fakePref_.value', originalAction); @@ -166,10 +214,31 @@ dropdown.value = option === undefined ? NO_REMAPPING_OPTION_LABEL : originalAction; }); + } else if (keyEvent) { + this.set('fakePref_.value', KEY_COMBINATION_OPTION_LABEL); + this.keyCombinationLabel_ = getKeyCombinationLabel(keyEvent) ?? + this.i18n('keyCombinationOptionLabel'); + + microTask.run(() => { + dropdown.value = KEY_COMBINATION_OPTION_LABEL; + }); } } /** + * Initialize the button remapping content and set up fake pref. + */ + private initializeCustomizeKey(): void { + if (!this.buttonRemappingList || + !this.buttonRemappingList[this.remappingIndex]) { + return; + } + this.buttonRemapping_ = this.buttonRemappingList[this.remappingIndex]; + this.setUpButtonMapTargets_(); + this.setUpRemappingActions_(); + } + + /** * Update device settings whenever the pref changes. */ private onSettingsChanged(): void {
diff --git a/chrome/browser/resources/bookmarks/store_client_mixin.ts b/chrome/browser/resources/bookmarks/store_client_mixin.ts index e6296852..882b30d 100644 --- a/chrome/browser/resources/bookmarks/store_client_mixin.ts +++ b/chrome/browser/resources/bookmarks/store_client_mixin.ts
@@ -61,19 +61,26 @@ } onStateChanged(newState: BookmarksPageState) { - this.watches_.forEach((watch) => { - const oldValue = this.get(watch.localProperty); - const newValue = watch.valueGetter(newState); + // Collect all local property changes into a single object. This + // reduces churn on the element in case one state change results in + // multiple local property changes. + const changes = this.watches_.reduce( + (result: Record<string, any>, {localProperty, valueGetter}) => { + const oldValue = this.get(localProperty); + const newValue = valueGetter(newState); - // Avoid poking Polymer unless something has actually changed. - // Reducers must return new objects rather than mutating existing - // objects, so any real changes will pass through correctly. - if (oldValue === newValue || newValue === undefined) { - return; - } + // Avoid poking Polymer unless something has actually changed. + // Reducers must return new objects rather than mutating + // existing objects, so any real changes will pass through + // correctly. + if (newValue !== oldValue && newValue !== undefined) { + result[localProperty] = newValue; + } + return result; + }, + {}); - this.set(watch.localProperty, newValue); - }); + this.setProperties(changes); } updateFromStore() {
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js index 1ae9c332..1c00b60 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
@@ -202,7 +202,7 @@ } this.setStopTimeout_( Dictation.Timeouts.NO_FOCUSED_IME_MS, - 'Dictation stopped automatically: No focused IME'); + Dictation.StopReason.NO_FOCUSED_IME); this.inputController_.connect(() => this.maybeStartSpeechRecognition_()); } @@ -262,18 +262,21 @@ /** * Sets the timeout to stop Dictation. * @param {number} durationMs - * @param {string=} debugInfo Optional debugging information for why Dictation + * @param {Dictation.StopReason=} reason Optional reason for why Dictation * stopped automatically. * @private */ - setStopTimeout_(durationMs, debugInfo) { + setStopTimeout_(durationMs, reason) { if (this.stopTimeoutId_ !== null) { clearTimeout(this.stopTimeoutId_); } this.stopTimeoutId_ = setTimeout(() => { this.stopDictation_(/*notify=*/ true); - if (debugInfo) { - console.log(debugInfo); + + if (reason === Dictation.StopReason.NO_FOCUSED_IME) { + chrome.accessibilityPrivate.showToast( + chrome.accessibilityPrivate.ToastType + .DICTATION_NO_FOCUSED_TEXT_FIELD); } }, durationMs); } @@ -540,12 +543,9 @@ InputController.IME_ENGINE_ID); } - /** - * Used to increase the NO_FOCUSED_IME_MS timeout to reduce the flakiness of - * Dictation tests on slower builds. For testing purposes only. - */ - increaseNoFocusedImeTimeoutForTesting() { - Dictation.Timeouts.NO_FOCUSED_IME_MS = 20 * 1000; + /** Used to set the NO_FOCUSED_IME_MS timeout for testing purposes only. */ + setNoFocusedImeTimeoutForTesting(duration) { + Dictation.Timeouts.NO_FOCUSED_IME_MS = duration; } /** @@ -628,3 +628,8 @@ NO_NEW_SPEECH_MS: 5 * 1000, NO_FOCUSED_IME_MS: 1000, }; + +/** @enum {string} */ +Dictation.StopReason = { + NO_FOCUSED_IME: 'Dictation stopped automatically: No focused IME', +};
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js index 67175ac..617f260 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_base.js
@@ -116,7 +116,7 @@ accessibilityCommon.dictation_.disablePumpkinForTesting(); // Increase Dictation's NO_FOCUSED_IME timeout to reduce flakiness on slower // builds. - accessibilityCommon.dictation_.increaseNoFocusedImeTimeoutForTesting(); + accessibilityCommon.dictation_.setNoFocusedImeTimeoutForTesting(20 * 1000); } /** @override */
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js index 5d854dda..764b7f4b 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test_support.js
@@ -20,9 +20,9 @@ domAutomationController.send('ready'); } - /** Increases Dictation timeouts for test stability. */ - increaseNoFocusedImeTimeout() { - this.dictation_.increaseNoFocusedImeTimeoutForTesting(); + /** Sets Dictation timeouts for test stability. */ + setNoFocusedImeTimeout(duration) { + this.dictation_.setNoFocusedImeTimeoutForTesting(duration); this.notifyCcTests_(); }
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js index 7f286bc9..e5fb082 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js +++ b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
@@ -73,6 +73,10 @@ this.SyntheticKeyboardEventType = {KEYDOWN: 'keydown', KEYUP: 'keyup'}; + this.ToastType = { + DICTATION_NO_FOCUSED_TEXT_FIELD: 'dictationNoFocusedTextField', + }; + /** @private {function<number, number>} */ this.boundsListener_ = null; @@ -484,4 +488,7 @@ await getFileBytes(`${pumpkinDir}/es_es/pumpkin_config.binarypb`); MockAccessibilityPrivate.pumpkinData_ = data; } + + /** @param {!chrome.accessibilityPrivate.ToastType} type */ + showToast(type) {} }
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html index 0f82596..71fc782 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html +++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html
@@ -1,6 +1,5 @@ <style include="cr-icons cr-shared-style"> :host { - --menu-item-margin: 12px; background: var(--color-new-tab-page-module-item-background); border-radius: var(--ntp-module-item-border-radius); display: flex; @@ -17,10 +16,6 @@ border: none; } - cr-action-menu { - --cr-menu-shadow: var(--ntp-menu-shadow); - } - #label-container { color: var(--color-new-tab-page-primary-foreground); display: flex; @@ -73,26 +68,12 @@ margin-inline-start: 12px; line-height: 20px; } - - .icon { - --cr-icon-ripple-size: 20px; - -webkit-mask-size: 16px; - background-color: transparent; - fill: var(--color-new-tab-page-secondary-foreground); - margin-inline-start: calc(-1 * var(--menu-item-margin)); - margin-inline-end: var(--menu-item-margin); - } - - hr { - background-color: var(--color-new-tab-page-module-context-menu-divider); - border: none; - height: 1px; - margin: 0; - } </style> <ntp-module-header-v2 + id="moduleHeaderElementV2" header-text="[[i18n('modulesJourneysResumeJourney', '')]]" on-menu-button-click="onMenuButtonClick_" + menu-item-groups="[[getMenuItemGroups_()]]" more-actions-text="[[i18n('modulesMoreActions', clusterLabel)]]"> </ntp-module-header-v2> <div id="label-container"> @@ -104,17 +85,3 @@ <span id="suggestion-chip-label">[[clusterLabel]]</span> </div> </div> - -<cr-action-menu id="actionMenu"> - <template is="dom-repeat" - items="[[getMenuItemGroups_()]]" as="group"> - <template is="dom-repeat" items="[[group]]"> - <button id="[[item.action]]" class="dropdown-item" - on-click="onButtonClick_" data-action$="[[item.action]]"> - <iron-icon class="icon cr-icon" icon="[[item.icon]]"></iron-icon> - [[item.text]] - </button> - </template> - <hr hidden$="[[!showDivider_(index)]]"> - </template> -</cr-action-menu>
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts index 35bbfdb..b810c23f 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts +++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts
@@ -8,23 +8,16 @@ import 'chrome://resources/cr_elements/cr_shared_style.css.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; -import {assert} from 'chrome://resources/js/assert_ts.js'; -import {DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {I18nMixin, loadTimeData} from '../../../i18n_setup.js'; +import {MenuItem, ModuleHeaderElementV2} from '../module_header.js'; import {getTemplate} from './header_tile.html.js'; -export interface MenuItem { - action: string; - icon: string; - text: string; -} - export interface HistoryClustersHeaderElementV2 { $: { - actionMenu: CrActionMenuElement, + moduleHeaderElementV2: ModuleHeaderElementV2, }; } @@ -56,21 +49,8 @@ clusterLabel: string; private suggestionChipHeaderEnabled_: boolean; - private onButtonClick_(e: DomRepeatEvent<MenuItem>) { - const {action} = e.model.item; - assert(action); - this.$.actionMenu.close(); - if (action === 'customize-module') { - this.dispatchEvent( - new Event('customize-module', {bubbles: true, composed: true})); - } else { - this.dispatchEvent(new Event( - `${action}-button-click`, {bubbles: true, composed: true})); - } - } - private onMenuButtonClick_(e: Event) { - this.$.actionMenu.showAt(e.target as HTMLElement); + this.$.moduleHeaderElementV2.showAt(e); } private getMenuItemGroups_(): MenuItem[][] { @@ -112,10 +92,6 @@ ], ]; } - - private showDivider_(index: number): boolean { - return index === 0; - } } declare global {
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/module_header.html b/chrome/browser/resources/new_tab_page/modules/v2/module_header.html index 361f0e2..5871497 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/module_header.html +++ b/chrome/browser/resources/new_tab_page/modules/v2/module_header.html
@@ -1,5 +1,6 @@ <style include="cr-icons"> :host { + --menu-item-margin: 12px; background: var(--color-new-tab-page-module-item-background); border-radius: var(--ntp-module-item-border-radius); display: flex; @@ -24,13 +25,33 @@ flex-grow: 1; } - cr-icon-button { + #menuButton { --cr-icon-button-icon-size: 20px; --cr-icon-button-fill-color: var(--color-new-tab-page-primary-foreground); --cr-icon-button-hover-background-color: var(--color-new-tab-page-control-background-hovered); margin-inline: 0 -6px; } + + #actionMenu { + --cr-menu-shadow: var(--ntp-menu-shadow); + } + + .action-menu-icon { + --cr-icon-ripple-size: 20px; + -webkit-mask-size: 16px; + background-color: transparent; + fill: var(--color-new-tab-page-secondary-foreground); + margin-inline-start: calc(-1 * var(--menu-item-margin)); + margin-inline-end: var(--menu-item-margin); + } + + #actionMenuDivider { + background-color: var(--color-new-tab-page-module-context-menu-divider); + border: none; + height: 1px; + margin: 0; + } </style> <div id="titleContainer"> <h2 id="title">[[headerText]]</h2> @@ -40,3 +61,20 @@ class="icon-more-vert" on-click="onMenuButtonClick_"> </cr-icon-button> </div> + +<cr-action-menu id="actionMenu"> + <template is="dom-repeat" + items="[[menuItemGroups]]" as="group"> + <template is="dom-repeat" items="[[group]]"> + <button id="[[item.action]]" class="dropdown-item" + on-click="onButtonClick_" data-action$="[[item.action]]"> + <iron-icon + class="action-menu-icon cr-icon" + icon="[[item.icon]]"> + </iron-icon> + [[item.text]] + </button> + </template> + <hr id="actionMenuDivider" hidden$="[[!showDivider_(index)]]"> + </template> +</cr-action-menu>
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts b/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts index 071a1c3..e190d329 100644 --- a/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts +++ b/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts
@@ -2,12 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import './icons.html.js'; +import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; + +import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; +import {DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {I18nMixin} from '../../i18n_setup.js'; import {getTemplate} from './module_header.html.js'; +export interface MenuItem { + action: string; + icon: string; + text: string; +} + + +export interface ModuleHeaderElementV2 { + $: { + actionMenu: CrActionMenuElement, + }; +} + /** Element that displays a header inside a module. */ export class ModuleHeaderElementV2 extends I18nMixin (PolymerElement) { @@ -23,15 +43,38 @@ return { headerText: String, moreActionsText: String, + menuItemGroups: Array, }; } headerText: string; + menuItemGroups: MenuItem[][]; moreActionsText: string; + showAt(e: Event) { + this.$.actionMenu.showAt(e.target as HTMLElement); + } + + private onButtonClick_(e: DomRepeatEvent<MenuItem>) { + const {action} = e.model.item; + assert(action); + this.$.actionMenu.close(); + if (action === 'customize-module') { + this.dispatchEvent( + new Event('customize-module', {bubbles: true, composed: true})); + } else { + this.dispatchEvent(new Event( + `${action}-button-click`, {bubbles: true, composed: true})); + } + } + private onMenuButtonClick_() { this.dispatchEvent(new Event('menu-button-click', {bubbles: true})); } + + private showDivider_(index: number): boolean { + return index === 0; + } } declare global {
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index dc77f9b..2baaa86 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -343,6 +343,11 @@ non_web_component_files += [ "autofill_page/passkeys_browser_proxy.ts" ] } + if (is_mac) { + non_web_component_files += + [ "a11y_page/mac_system_settings_browser_proxy.ts" ] + } + # -----------------non_web_component_files end ------------------------------- icons_html_files = [
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.ts b/chrome/browser/resources/settings/a11y_page/a11y_page.ts index 8de27a8..980b9c1 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.ts +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.ts
@@ -23,9 +23,6 @@ import {CaptionsBrowserProxyImpl} from '/shared/settings/a11y_page/captions_browser_proxy.js'; // </if> -// <if expr="is_macosx"> -import {MacSystemSettingsBrowserProxyImpl} from '/shared/settings/mac_system_settings_browser_proxy.js'; -// </if> // clang-format on import {SettingsToggleButtonElement} from '/shared/settings/controls/settings_toggle_button.js'; import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; @@ -41,9 +38,14 @@ // clang-format off // <if expr="not is_chromeos"> import {LanguageHelper, LanguagesModel} from '../languages_page/languages_types.js'; + +// </if> +// <if expr="is_macosx"> +import {MacSystemSettingsBrowserProxyImpl} from './mac_system_settings_browser_proxy.js'; // </if> // clang-format on + const SettingsA11yPageElementBase = WebUiListenerMixin(BaseMixin(PolymerElement));
diff --git a/chrome/browser/resources/settings_shared/mac_system_settings_browser_proxy.ts b/chrome/browser/resources/settings/a11y_page/mac_system_settings_browser_proxy.ts similarity index 100% rename from chrome/browser/resources/settings_shared/mac_system_settings_browser_proxy.ts rename to chrome/browser/resources/settings/a11y_page/mac_system_settings_browser_proxy.ts
diff --git a/chrome/browser/resources/settings_shared/BUILD.gn b/chrome/browser/resources/settings_shared/BUILD.gn index 2691b09..609b1c8c 100644 --- a/chrome/browser/resources/settings_shared/BUILD.gn +++ b/chrome/browser/resources/settings_shared/BUILD.gn
@@ -40,10 +40,6 @@ "privacy_page/privacy_page_browser_proxy.ts", ] - if (is_mac) { - non_web_component_files += [ "mac_system_settings_browser_proxy.ts" ] - } - ts_composite = true ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts",
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc index 4e963ac9d..ede2c0c 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc
@@ -189,6 +189,11 @@ return ".Enterprise"; } +void ChromeEnterpriseRealTimeUrlLookupService::Shutdown() { + token_fetcher_.reset(); + RealTimeUrlLookupServiceBase::Shutdown(); +} + bool ChromeEnterpriseRealTimeUrlLookupService::ShouldIncludeCredentials() const { return false;
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h index cba3c1e6..fca6bdd5 100644 --- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h +++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h
@@ -60,6 +60,7 @@ bool CanCheckSafeBrowsingHighConfidenceAllowlist() const override; bool CanSendRTSampleRequest() const override; std::string GetMetricSuffix() const override; + void Shutdown() override; private: // RealTimeUrlLookupServiceBase:
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_factory.cc b/chrome/browser/safe_browsing/client_side_detection_service_factory.cc index 1f5de2b..003c7ff 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_factory.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_factory.cc
@@ -49,7 +49,8 @@ .WithAshInternals(ProfileSelection::kNone) .Build()) {} -KeyedService* ClientSideDetectionServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ClientSideDetectionServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); @@ -64,7 +65,7 @@ base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); - return new ClientSideDetectionService( + return std::make_unique<ClientSideDetectionService>( std::make_unique<ChromeClientSideDetectionServiceDelegate>(profile), opt_guide, background_task_runner); }
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_factory.h b/chrome/browser/safe_browsing/client_side_detection_service_factory.h index 601336c..9f47092c 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_factory.h +++ b/chrome/browser/safe_browsing/client_side_detection_service_factory.h
@@ -39,7 +39,7 @@ ~ClientSideDetectionServiceFactory() override = default; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc index dfb654e..48ad89e 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc
@@ -234,6 +234,11 @@ content_analysis_request_.mutable_request_data()->set_password(password); } +void BinaryUploadService::Request::set_reason( + enterprise_connectors::ContentAnalysisRequest::Reason reason) { + content_analysis_request_.set_reason(reason); +} + std::string BinaryUploadService::Request::SetRandomRequestToken() { DCHECK(request_token().empty()); @@ -301,6 +306,11 @@ return content_analysis_request_.request_data().password(); } +enterprise_connectors::ContentAnalysisRequest::Reason +BinaryUploadService::Request::reason() const { + return content_analysis_request_.reason(); +} + void BinaryUploadService::Request::StartRequest() { if (!request_start_callback_.is_null()) std::move(request_start_callback_).Run(*this);
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h index 76852bc..be9fe62 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h
@@ -180,6 +180,8 @@ enterprise_connectors::ContentMetaData::PrintMetadata::PrinterType printer_type); void set_password(const std::string& password); + void set_reason( + enterprise_connectors::ContentAnalysisRequest::Reason reason); std::string SetRandomRequestToken(); @@ -197,6 +199,7 @@ uint64_t user_action_requests_count() const; GURL tab_url() const; const std::string& password() const; + enterprise_connectors::ContentAnalysisRequest::Reason reason() const; // Called when beginning to try upload. void StartRequest();
diff --git a/chrome/browser/safe_browsing/network_context_service_factory.cc b/chrome/browser/safe_browsing/network_context_service_factory.cc index 5e6a7a2..c006e64d 100644 --- a/chrome/browser/safe_browsing/network_context_service_factory.cc +++ b/chrome/browser/safe_browsing/network_context_service_factory.cc
@@ -34,10 +34,11 @@ NetworkContextServiceFactory::~NetworkContextServiceFactory() = default; -KeyedService* NetworkContextServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +NetworkContextServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - return new NetworkContextService(profile); + return std::make_unique<NetworkContextService>(profile); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/network_context_service_factory.h b/chrome/browser/safe_browsing/network_context_service_factory.h index d0dc0e4..5bd2d77 100644 --- a/chrome/browser/safe_browsing/network_context_service_factory.h +++ b/chrome/browser/safe_browsing/network_context_service_factory.h
@@ -33,7 +33,7 @@ ~NetworkContextServiceFactory() override; // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc index 0aa3b19..6e5368c 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
@@ -39,11 +39,12 @@ .WithGuest(ProfileSelection::kOwnInstance) .Build()) {} -KeyedService* -SafeBrowsingNavigationObserverManagerFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { +std::unique_ptr<KeyedService> SafeBrowsingNavigationObserverManagerFactory:: + BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - return new SafeBrowsingNavigationObserverManager(profile->GetPrefs()); + return std::make_unique<SafeBrowsingNavigationObserverManager>( + profile->GetPrefs()); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h index 72a06d63..bedd33a 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h
@@ -41,7 +41,7 @@ ~SafeBrowsingNavigationObserverManagerFactory() override = default; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/safe_browsing/url_lookup_service_factory.cc b/chrome/browser/safe_browsing/url_lookup_service_factory.cc index 6d8507e..d1db370 100644 --- a/chrome/browser/safe_browsing/url_lookup_service_factory.cc +++ b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
@@ -62,7 +62,8 @@ DependsOn(NetworkContextServiceFactory::GetInstance()); } -KeyedService* RealTimeUrlLookupServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +RealTimeUrlLookupServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { if (!g_browser_process->safe_browsing_service()) { return nullptr; @@ -72,7 +73,7 @@ std::make_unique<network::CrossThreadPendingSharedURLLoaderFactory>( g_browser_process->safe_browsing_service()->GetURLLoaderFactory( profile)); - return new RealTimeUrlLookupService( + return std::make_unique<RealTimeUrlLookupService>( network::SharedURLLoaderFactory::Create(std::move(url_loader_factory)), VerdictCacheManagerFactory::GetForProfile(profile), base::BindRepeating(
diff --git a/chrome/browser/safe_browsing/url_lookup_service_factory.h b/chrome/browser/safe_browsing/url_lookup_service_factory.h index 0c23b586..7861538 100644 --- a/chrome/browser/safe_browsing/url_lookup_service_factory.h +++ b/chrome/browser/safe_browsing/url_lookup_service_factory.h
@@ -43,7 +43,7 @@ ~RealTimeUrlLookupServiceFactory() override = default; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/search/background/ntp_background_service_factory.cc b/chrome/browser/search/background/ntp_background_service_factory.cc index 7842cb95..85aa3ca 100644 --- a/chrome/browser/search/background/ntp_background_service_factory.cc +++ b/chrome/browser/search/background/ntp_background_service_factory.cc
@@ -41,12 +41,13 @@ NtpBackgroundServiceFactory::~NtpBackgroundServiceFactory() = default; -KeyedService* NtpBackgroundServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +NtpBackgroundServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { // TODO(crbug.com/914898): Background service URLs should be // configurable server-side, so they can be changed mid-release. auto url_loader_factory = context->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess(); - return new NtpBackgroundService(url_loader_factory); + return std::make_unique<NtpBackgroundService>(url_loader_factory); }
diff --git a/chrome/browser/search/background/ntp_background_service_factory.h b/chrome/browser/search/background/ntp_background_service_factory.h index c45ff24d..297640d7 100644 --- a/chrome/browser/search/background/ntp_background_service_factory.h +++ b/chrome/browser/search/background/ntp_background_service_factory.h
@@ -29,7 +29,7 @@ ~NtpBackgroundServiceFactory() override; // Overridden from BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/serial/serial_chooser_context_factory.cc b/chrome/browser/serial/serial_chooser_context_factory.cc index 733d28d..66751d94 100644 --- a/chrome/browser/serial/serial_chooser_context_factory.cc +++ b/chrome/browser/serial/serial_chooser_context_factory.cc
@@ -22,9 +22,11 @@ SerialChooserContextFactory::~SerialChooserContextFactory() = default; -KeyedService* SerialChooserContextFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +SerialChooserContextFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new SerialChooserContext(Profile::FromBrowserContext(context)); + return std::make_unique<SerialChooserContext>( + Profile::FromBrowserContext(context)); } // static
diff --git a/chrome/browser/serial/serial_chooser_context_factory.h b/chrome/browser/serial/serial_chooser_context_factory.h index 65b56de..98a473eb 100644 --- a/chrome/browser/serial/serial_chooser_context_factory.h +++ b/chrome/browser/serial/serial_chooser_context_factory.h
@@ -28,7 +28,7 @@ ~SerialChooserContextFactory() override; // BrowserContextKeyedServiceFactory methods: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; void BrowserContextShutdown(content::BrowserContext* context) override; };
diff --git a/chrome/browser/sync/test/integration/sync_app_list_helper.h b/chrome/browser/sync/test/integration/sync_app_list_helper.h index 546c56d..0aa2ce9 100644 --- a/chrome/browser/sync/test/integration/sync_app_list_helper.h +++ b/chrome/browser/sync/test/integration/sync_app_list_helper.h
@@ -64,7 +64,7 @@ ChromeAppListItem* item, const std::string& label); - raw_ptr<SyncTest, ExperimentalAsh> test_ = nullptr; + raw_ptr<SyncTest, DanglingUntriaged | ExperimentalAsh> test_ = nullptr; bool setup_completed_ = false; };
diff --git a/chrome/browser/ui/android/cars/BUILD.gn b/chrome/browser/ui/android/cars/BUILD.gn index 8851af9..56a2f62e 100644 --- a/chrome/browser/ui/android/cars/BUILD.gn +++ b/chrome/browser/ui/android/cars/BUILD.gn
@@ -5,12 +5,33 @@ import("//build/config/android/rules.gni") android_library("java") { + sources = [ "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java" ] + + deps = [ "//base:base_java" ] + + public_deps = [ ":delegate_java" ] +} + +android_library("delegate_java") { sources = [ "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegate.java", - "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java", + "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java", ] deps = [ "//base:base_java" ] + + # Add the actual implementation where necessary so that downstream targets + # can provide their own implementations. + jar_excluded_patterns = [ "*/DrivingRestrictionsDelegateImpl.class" ] +} + +android_library("delegate_public_impl_java") { + sources = [ "java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java" ] + + deps = [ + ":delegate_java", + "//base:base_java", + ] } robolectric_library("junit") {
diff --git a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java new file mode 100644 index 0000000..f209ac7a --- /dev/null +++ b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsDelegateImpl.java
@@ -0,0 +1,19 @@ +// 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.chrome.browser.ui.cars; + +import org.chromium.base.Callback; + +/** + * Instantiable version of {@link DrivingRestrictionsDelegate}, don't add anything to this class. + * Downstream targets may provide a different implementation. In GN, we specify that + * {@link DrivingRestrictionsDelegate} is compiled separately from its implementation; other + * projects may specify a different DrivingRestrictionsDelegate via GN. + */ +class DrivingRestrictionsDelegateImpl extends DrivingRestrictionsDelegate { + DrivingRestrictionsDelegateImpl(Callback<Boolean> requiresDrivingOptimizationsCallback) { + super(requiresDrivingOptimizationsCallback); + } +}
diff --git a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java index bb02d3b..0c7b759 100644 --- a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java +++ b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManager.java
@@ -15,7 +15,7 @@ public class DrivingRestrictionsManager { private static DrivingRestrictionsManager sInstance; - private DrivingRestrictionsDelegate mDelegate; + private DrivingRestrictionsDelegateImpl mDelegate; private boolean mMonitoring; /** @@ -26,7 +26,8 @@ } DrivingRestrictionsManager() { - mDelegate = new DrivingRestrictionsDelegate(this::onRequiresDistractionOptimizationChanged); + mDelegate = + new DrivingRestrictionsDelegateImpl(this::onRequiresDistractionOptimizationChanged); updateMonitoring(ApplicationStatus.getStateForApplication()); ApplicationStatus.registerApplicationStateListener(newState -> updateMonitoring(newState)); @@ -50,11 +51,15 @@ } } - void setDelegateForTesting(DrivingRestrictionsDelegate delegate) { + void setDelegateForTesting(DrivingRestrictionsDelegateImpl delegate) { mDelegate = delegate; } - DrivingRestrictionsDelegate getDelegateForTesting() { + DrivingRestrictionsDelegateImpl getDelegateForTesting() { return mDelegate; } + + static DrivingRestrictionsManager getInstanceForTesting() { + return sInstance; + } }
diff --git a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java index 1edea52e..6aa3145d 100644 --- a/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java +++ b/chrome/browser/ui/android/cars/java/src/org/chromium/chrome/browser/ui/cars/DrivingRestrictionsManagerTest.java
@@ -28,7 +28,7 @@ public class DrivingRestrictionsManagerTest { private DrivingRestrictionsManager mManager; @Spy - private DrivingRestrictionsDelegate mSpyDelegate; + private DrivingRestrictionsDelegateImpl mSpyDelegate; @Before public void setUp() {
diff --git a/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/SurveyControllerProvider.java b/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/SurveyControllerProvider.java index d3255dba..f5658be8 100644 --- a/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/SurveyControllerProvider.java +++ b/chrome/browser/ui/android/hats/internal/java/src/org/chromium/chrome/browser/ui/hats/SurveyControllerProvider.java
@@ -7,13 +7,14 @@ /** * Util class that creates a new SurveyController. */ -class SurveyControllerProvider { +// TODO(crbug/1400731): Change to package private once public references are removed. +public class SurveyControllerProvider { private SurveyControllerProvider() {} /** * @return A new instance of survey controller. */ - static SurveyController create() { + public static SurveyController create() { return new SurveyController() {}; } }
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc index 6d060a49c..8f2b37e 100644 --- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc +++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.cc
@@ -117,3 +117,5 @@ const absl::optional<std::vector<ash::DictationBubbleHintType>>& hints) {} void FakeAccessibilityController::SilenceSpokenFeedback() {} + +void FakeAccessibilityController::ShowToast(ash::AccessibilityToastType type) {}
diff --git a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h index 3fc2c32..808dcc11 100644 --- a/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h +++ b/chrome/browser/ui/ash/accessibility/fake_accessibility_controller.h
@@ -77,6 +77,7 @@ const absl::optional<std::vector<ash::DictationBubbleHintType>>& hints) override; void SilenceSpokenFeedback() override; + void ShowToast(ash::AccessibilityToastType type) override; private: bool was_client_set_ = false;
diff --git a/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.cc b/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.cc index a6d2a79..c2d08fb 100644 --- a/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.cc +++ b/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.cc
@@ -37,7 +37,8 @@ GetInstance()->GetServiceForBrowserContext(context, /*create=*/true)); } -KeyedService* CalendarKeyedServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> + CalendarKeyedServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* const profile = Profile::FromBrowserContext(context); user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile); @@ -47,7 +48,7 @@ if (!user->HasGaiaAccount()) return nullptr; - return new CalendarKeyedService(profile, user->GetAccountId()); + return std::make_unique<CalendarKeyedService>(profile, user->GetAccountId()); } } // namespace ash
diff --git a/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.h b/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.h index a72fe94e..f6b7e65 100644 --- a/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.h +++ b/chrome/browser/ui/ash/calendar/calendar_keyed_service_factory.h
@@ -27,7 +27,7 @@ protected: // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override {}
diff --git a/chrome/browser/ui/ash/quick_settings_integration_test.cc b/chrome/browser/ui/ash/quick_settings_integration_test.cc index 559c54b..42702a04 100644 --- a/chrome/browser/ui/ash/quick_settings_integration_test.cc +++ b/chrome/browser/ui/ash/quick_settings_integration_test.cc
@@ -9,9 +9,12 @@ #include "ash/system/model/system_tray_model.h" #include "base/test/gtest_tags.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/crosapi/browser_manager_observer.h" +#include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/chromeos/crosier/interactive_ash_test.h" #include "ui/base/interaction/element_identifier.h" +#include "ui/base/interaction/state_observer.h" namespace ash { namespace { @@ -89,5 +92,78 @@ Log("Test complete")); } +// Testing with Lacros requires a VM or DUT. +#if BUILDFLAG(IS_CHROMEOS_DEVICE) + +// Observes the crosapi browser manager to detect Lacros startup. Signals with a +// boolean that is true if lacros is running, false otherwise. +class TestBrowserManagerObserver : public ui::test::ObservationStateObserver< + bool, + crosapi::BrowserManager, + crosapi::BrowserManagerObserver> { + public: + TestBrowserManagerObserver() + : ObservationStateObserver(crosapi::BrowserManager::Get()) {} + + // ui::test::ObservationStateObserver: + bool GetStateObserverInitialState() const override { + // Tests in this suite do not have a lacros browser window open at start. + return false; + } + + // crosapi::BrowserManagerObserver: + void OnStateChanged() override { + const bool is_lacros_running = + crosapi::BrowserManager::Get()->IsRunningOrWillRun(); + OnStateObserverStateChanged(is_lacros_running); + } +}; + +// Tests of ash quick settings that assume the primary browser is Lacros. +class QuickSettingsLacrosIntegrationTest : public QuickSettingsIntegrationTest { + public: + QuickSettingsLacrosIntegrationTest() { + feature_list_.InitAndEnableFeature(features::kLacrosOnly); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(QuickSettingsLacrosIntegrationTest, ManagedDeviceInfo) { + ASSERT_TRUE(crosapi::browser_util::IsLacrosEnabled()); + + base::AddFeatureIdTagToTestResult( + "screenplay-f0a4bd11-a2bc-4596-a4fc-2a62c7277965"); + + SetupContextWidget(); + + // Simulate enterprise information being available. + GetEnterpriseDomainModel()->SetDeviceEnterpriseInfo( + DeviceEnterpriseInfo{"example.com", /*active_directory_managed=*/false, + ManagementDeviceMode::kChromeEnterprise}); + + DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(TestBrowserManagerObserver, kLacrosState); + + RunTestSequence( + Log("Opening quick settings bubble"), + PressButton(kUnifiedSystemTrayElementId), + WaitForShow(kQuickSettingsViewElementId), + + Log("Pressing enterprise managed view"), + ObserveState(kLacrosState, + std::make_unique<TestBrowserManagerObserver>()), + PressButton(kEnterpriseManagedView), + + Log("Waiting for the lacros browser to start"), + WaitForState(kLacrosState, true), + + // TODO(jamescook): Verify that Lacros loaded the management URL. + + Log("Test complete")); +} + +#endif // BUILDFLAG(IS_CHROMEOS_DEVICE) + } // namespace } // namespace ash
diff --git a/chrome/browser/ui/find_bar/find_bar_state_factory.cc b/chrome/browser/ui/find_bar/find_bar_state_factory.cc index 377a61b..944347fb 100644 --- a/chrome/browser/ui/find_bar/find_bar_state_factory.cc +++ b/chrome/browser/ui/find_bar/find_bar_state_factory.cc
@@ -32,7 +32,8 @@ FindBarStateFactory::~FindBarStateFactory() = default; -KeyedService* FindBarStateFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +FindBarStateFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new FindBarState(context); + return std::make_unique<FindBarState>(context); }
diff --git a/chrome/browser/ui/find_bar/find_bar_state_factory.h b/chrome/browser/ui/find_bar/find_bar_state_factory.h index 57966a0..183113d 100644 --- a/chrome/browser/ui/find_bar/find_bar_state_factory.h +++ b/chrome/browser/ui/find_bar/find_bar_state_factory.h
@@ -26,7 +26,7 @@ ~FindBarStateFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.cc b/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.cc index 2f5998b..c6d3147 100644 --- a/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.cc +++ b/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.cc
@@ -36,7 +36,8 @@ GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true)); } -KeyedService* PerformanceControlsHatsServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +PerformanceControlsHatsServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { if (context->IsOffTheRecord() || (!base::FeatureList::IsEnabled( @@ -68,5 +69,5 @@ return nullptr; } - return new PerformanceControlsHatsService(profile); + return std::make_unique<PerformanceControlsHatsService>(profile); }
diff --git a/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.h b/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.h index 537fed1..72b2e6a 100644 --- a/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.h +++ b/chrome/browser/ui/performance_controls/performance_controls_hats_service_factory.h
@@ -23,7 +23,7 @@ ~PerformanceControlsHatsServiceFactory() override = default; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc index c80ebcff..add5b82d 100644 --- a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc +++ b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc
@@ -39,9 +39,9 @@ NotificationPermissionsReviewServiceFactory:: ~NotificationPermissionsReviewServiceFactory() = default; -KeyedService* -NotificationPermissionsReviewServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - return new NotificationPermissionsReviewService( +std::unique_ptr<KeyedService> NotificationPermissionsReviewServiceFactory:: + BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const { + return std::make_unique<NotificationPermissionsReviewService>( HostContentSettingsMapFactory::GetForProfile(context)); }
diff --git a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h index 46094348..9c38adc 100644 --- a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h +++ b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h
@@ -39,7 +39,7 @@ ~NotificationPermissionsReviewServiceFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc b/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc index 76132bb..60847bf 100644 --- a/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc +++ b/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc
@@ -46,10 +46,12 @@ PasswordStatusCheckServiceFactory::~PasswordStatusCheckServiceFactory() = default; -KeyedService* PasswordStatusCheckServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +PasswordStatusCheckServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { if (!base::FeatureList::IsEnabled(features::kSafetyHub)) { return nullptr; } - return new PasswordStatusCheckService(Profile::FromBrowserContext(context)); + return std::make_unique<PasswordStatusCheckService>( + Profile::FromBrowserContext(context)); }
diff --git a/chrome/browser/ui/safety_hub/password_status_check_service_factory.h b/chrome/browser/ui/safety_hub/password_status_check_service_factory.h index 90e06fa4..082ba2d 100644 --- a/chrome/browser/ui/safety_hub/password_status_check_service_factory.h +++ b/chrome/browser/ui/safety_hub/password_status_check_service_factory.h
@@ -34,7 +34,7 @@ ~PasswordStatusCheckServiceFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/side_panel/read_anything/read_anything_side_panel_controller_utils.h b/chrome/browser/ui/side_panel/read_anything/read_anything_side_panel_controller_utils.h index 6f45bee..a25b197 100644 --- a/chrome/browser/ui/side_panel/read_anything/read_anything_side_panel_controller_utils.h +++ b/chrome/browser/ui/side_panel/read_anything/read_anything_side_panel_controller_utils.h
@@ -7,13 +7,8 @@ class Browser; -namespace content { -class WebContents; -} // namespace content - // Used for reading mode option in context menu. void ShowReadAnythingSidePanel(Browser* browser); bool IsReadAnythingEntryShowing(Browser* browser); -void CreateAndRegisterEntry(content::WebContents* web_contents); #endif // CHROME_BROWSER_UI_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_SIDE_PANEL_CONTROLLER_UTILS_H_
diff --git a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc index dac40e01..7386f612a 100644 --- a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc +++ b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop.cc
@@ -149,6 +149,8 @@ return; } + data.reason = enterprise_connectors::ContentAnalysisRequest::DRAG_AND_DROP; + // Collect the data that needs to be scanned. if (!drop_data.url_title.empty()) data.text.push_back(base::UTF16ToUTF8(drop_data.url_title));
diff --git a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc index e21738d..f059aadc 100644 --- a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc +++ b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc
@@ -33,6 +33,78 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" +class DragDropTestContentAnalysisDelegate + : public enterprise_connectors::test::FakeContentAnalysisDelegate { + public: + DragDropTestContentAnalysisDelegate(base::RepeatingClosure delete_closure, + StatusCallback status_callback, + std::string dm_token, + content::WebContents* web_contents, + Data data, + CompletionCallback callback) + : enterprise_connectors::test::FakeContentAnalysisDelegate( + delete_closure, + std::move(status_callback), + std::move(dm_token), + web_contents, + std::move(data), + std::move(callback)) {} + + static std::unique_ptr<ContentAnalysisDelegate> Create( + base::RepeatingClosure delete_closure, + StatusCallback status_callback, + std::string dm_token, + content::WebContents* web_contents, + Data data, + CompletionCallback callback) { + auto ret = std::make_unique<DragDropTestContentAnalysisDelegate>( + delete_closure, std::move(status_callback), std::move(dm_token), + web_contents, std::move(data), std::move(callback)); + enterprise_connectors::FilesRequestHandler::SetFactoryForTesting( + base::BindRepeating( + &enterprise_connectors::test::FakeFilesRequestHandler::Create, + base::BindRepeating(&DragDropTestContentAnalysisDelegate:: + FakeUploadFileForDeepScanning, + base::Unretained(ret.get())))); + return ret; + } + + private: + void UploadTextForDeepScanning( + std::unique_ptr<safe_browsing::BinaryUploadService::Request> request) + override { + ASSERT_EQ(request->reason(), + enterprise_connectors::ContentAnalysisRequest::DRAG_AND_DROP); + + enterprise_connectors::test::FakeContentAnalysisDelegate:: + UploadTextForDeepScanning(std::move(request)); + } + + void UploadImageForDeepScanning( + std::unique_ptr<safe_browsing::BinaryUploadService::Request> request) + override { + ASSERT_EQ(request->reason(), + enterprise_connectors::ContentAnalysisRequest::DRAG_AND_DROP); + + enterprise_connectors::test::FakeContentAnalysisDelegate:: + UploadImageForDeepScanning(std::move(request)); + } + + void FakeUploadFileForDeepScanning( + safe_browsing::BinaryUploadService::Result result, + const base::FilePath& path, + std::unique_ptr<safe_browsing::BinaryUploadService::Request> request, + enterprise_connectors::test::FakeFilesRequestHandler:: + FakeFileRequestCallback callback) override { + ASSERT_EQ(request->reason(), + enterprise_connectors::ContentAnalysisRequest::DRAG_AND_DROP); + + enterprise_connectors::test::FakeContentAnalysisDelegate:: + FakeUploadFileForDeepScanning(result, path, std::move(request), + std::move(callback)); + } +}; + class ChromeWebContentsViewDelegateHandleOnPerformDrop : public testing::Test { public: ChromeWebContentsViewDelegateHandleOnPerformDrop() { @@ -118,9 +190,8 @@ return response; }); enterprise_connectors::ContentAnalysisDelegate::SetFactoryForTesting( - base::BindRepeating( - &enterprise_connectors::test::FakeContentAnalysisDelegate::Create, - run_loop_->QuitClosure(), callback, "dm_token")); + base::BindRepeating(&DragDropTestContentAnalysisDelegate::Create, + run_loop_->QuitClosure(), callback, "dm_token")); enterprise_connectors::ContentAnalysisDelegate::DisableUIForTesting(); enterprise_connectors::ContentAnalysisDelegate:: SetOnAckAllRequestsCallbackForTesting(base::BindOnce(
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc index 55dd2c2..6dafa2a 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.cc
@@ -34,9 +34,10 @@ SavedTabGroupServiceFactory::~SavedTabGroupServiceFactory() = default; -KeyedService* SavedTabGroupServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +SavedTabGroupServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { DCHECK(context); Profile* profile = Profile::FromBrowserContext(context); - return new SavedTabGroupKeyedService(profile); + return std::make_unique<SavedTabGroupKeyedService>(profile); }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h index d39a3472..6d53625 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h
@@ -25,7 +25,7 @@ friend base::NoDestructor<SavedTabGroupServiceFactory>; // BrowserContextKeyedServiceFactory overrides. - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc index 3385d6b..2525bd2 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -107,8 +107,6 @@ const char kCreditCardAndAddressUploadForm[] = "/credit_card_upload_form_address_and_cc.html"; const char kCreditCardUploadForm[] = "/credit_card_upload_form_cc.html"; -const char kCreditCardAndShippingUploadForm[] = - "/credit_card_upload_form_shipping_address.html"; const char kURLGetUploadDetailsRequest[] = "https://payments.google.com/payments/apis/chromepaymentsservice/" "getdetailsforsavecard"; @@ -133,6 +131,8 @@ namespace autofill { +// Param of the test indicates whether the experiment to reposition the bubble +// ToS message is enabled. class SaveCardBubbleViewsFullFormBrowserTest : public SyncTest, public CreditCardSaveManager::ObserverForTest, @@ -466,14 +466,15 @@ // Should be called for credit_card_upload_form_shipping_address.html. void FillFormWithConflictingName() { - NavigateToAndWaitForForm(kCreditCardAndShippingUploadForm); + NavigateToAndWaitForForm(kCreditCardAndAddressUploadForm); content::WebContents* web_contents = GetActiveWebContents(); const std::string click_fill_button_js = "(function() { document.getElementById('fill_form').click(); })();"; ASSERT_TRUE(content::ExecJs(web_contents, click_fill_button_js)); const std::string click_conflicting_name_button_js = - "(function() { document.getElementById('conflicting_name').click(); " + "(function() { " + "document.getElementById('fill_conflicting_name').click(); " "})();"; ASSERT_TRUE( content::ExecJs(web_contents, click_conflicting_name_button_js)); @@ -570,21 +571,6 @@ ASSERT_TRUE(content::ExecJs(web_contents, click_clear_address_button_js)); } - // Should be called for credit_card_upload_form_shipping_address.html. - void FillFormWithConflictingPostalCode() { - NavigateToAndWaitForForm(kCreditCardAndShippingUploadForm); - content::WebContents* web_contents = GetActiveWebContents(); - const std::string click_fill_button_js = - "(function() { document.getElementById('fill_form').click(); })();"; - ASSERT_TRUE(content::ExecJs(web_contents, click_fill_button_js)); - - const std::string click_conflicting_postal_code_button_js = - "(function() { " - "document.getElementById('conflicting_postal_code').click(); })();"; - ASSERT_TRUE( - content::ExecJs(web_contents, click_conflicting_postal_code_button_js)); - } - void SetUploadDetailsRpcPaymentsAccepts() { test_url_loader_factory()->AddResponse(kURLGetUploadDetailsRequest, kResponseGetUploadDetailsSuccess); @@ -1585,23 +1571,19 @@ // Tests the upload save logic. Ensures that Chrome lets Payments decide whether // upload save should be offered, even if multiple conflicting names are // detected. -// TODO(crbug.com/1425364): Fix flakiness. IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - DISABLED_Logic_ShouldAttemptToOfferToSaveIfNamesConflict) { + Logic_ShouldAttemptToOfferToSaveIfNamesConflict) { // Start sync. ASSERT_TRUE(SetupSync()); - // Submit first shipping address form with a conflicting name. + // Submitting the form should still start the flow of asking Payments if + // Chrome should offer to save the card to Google, even though the name + // in the credit card form conflicts with the one in the address form. + ResetEventWaiterForSequence({DialogEvent::REQUESTED_UPLOAD_SAVE}); FillFormWithConflictingName(); SubmitForm(); - // Submitting the form should still start the flow of asking Payments if - // Chrome should offer to save the card to Google, even though the name - // conflicts with the previous form. - ResetEventWaiterForSequence({DialogEvent::REQUESTED_UPLOAD_SAVE}); - FillForm(); - SubmitForm(); ASSERT_TRUE(WaitForObservedEvent()); } @@ -1627,21 +1609,24 @@ // postal codes are detected. IN_PROC_BROWSER_TEST_P( SaveCardBubbleViewsFullFormBrowserTestWithAutofillUpstream, - // TODO(crbug.com/1439213): Re-enable this test - DISABLED_Logic_ShouldAttemptToOfferToSaveIfPostalCodesConflict) { + Logic_ShouldAttemptToOfferToSaveIfPostalCodesConflict) { // Start sync. ASSERT_TRUE(SetupSync()); + // Add one address to the profile. This address should have a different + // zipcode than the one to be filled in the form below. + AutofillProfile address_profile = test::GetFullProfile(); + address_profile.SetRawInfo(ADDRESS_HOME_ZIP, u"91111"); + PersonalDataManagerFactory::GetForProfile(GetProfile(0)) + ->AddProfile(address_profile); - // Submit first shipping address form with a conflicting postal code. - FillFormWithConflictingPostalCode(); - SubmitForm(); - - // Submitting the form should still start the flow of asking Payments if - // Chrome should offer to save the card to Google, even though the postal code - // conflicts with the previous form. + // Submitting the form should start the flow of asking Payments if Chrome + // should offer to save the card to Google, even though the postal codes in + // the two known addresses conflict - the address filled in the form has + // zipcode of 94043, comparing to the pre-existing profile zipcode of 91111. ResetEventWaiterForSequence({DialogEvent::REQUESTED_UPLOAD_SAVE}); FillForm(); SubmitForm(); + ASSERT_TRUE(WaitForObservedEvent()); }
diff --git a/chrome/browser/ui/views/editor_menu/editor_menu_view.cc b/chrome/browser/ui/views/editor_menu/editor_menu_view.cc index 0d6723fb..d2086c8 100644 --- a/chrome/browser/ui/views/editor_menu/editor_menu_view.cc +++ b/chrome/browser/ui/views/editor_menu/editor_menu_view.cc
@@ -23,9 +23,11 @@ #include "ui/gfx/geometry/rect.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/background.h" +#include "ui/views/controls/button/image_button.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/flex_layout.h" +#include "ui/views/layout/flex_layout_types.h" #include "ui/views/layout/flex_layout_view.h" #include "ui/views/layout/layout_manager.h" #include "ui/views/view.h" @@ -43,6 +45,10 @@ constexpr gfx::Insets kTitleContainerInsets = gfx::Insets::TLBR(10, 16, 10, 10); +constexpr char16_t kSettingsTooltipString[] = u"Settings"; +constexpr int kSettingsButtonSizeDip = 32; +constexpr int kSettingsIconSizeDip = 20; + constexpr int kChipsContainerVerticalSpacingDip = 16; constexpr gfx::Insets kChipsMargin = gfx::Insets::TLBR(0, 8, kChipsContainerVerticalSpacingDip, 0); @@ -139,12 +145,32 @@ auto* title = title_container_->AddChildView( std::make_unique<views::Label>(kContainerTitle)); - // TODO(b/295078199): Add Settings icon. + auto* spacer = + title_container_->AddChildView(std::make_unique<views::View>()); + layout->SetFlexForView(spacer, 1); + + auto* button_container = + title_container_->AddChildView(std::make_unique<views::FlexLayoutView>()); + button_container->SetMainAxisAlignment(views::LayoutAlignment::kCenter); + button_container->SetCrossAxisAlignment(views::LayoutAlignment::kCenter); + button_container->SetPreferredSize( + gfx::Size(kSettingsButtonSizeDip, kSettingsButtonSizeDip)); + + settings_button_ = + button_container->AddChildView(std::make_unique<views::ImageButton>()); + settings_button_->SetTooltipText(kSettingsTooltipString); + settings_button_->SetImageModel( + views::Button::STATE_NORMAL, + ui::ImageModel::FromVectorIcon(vector_icons::kSettingsOutlineIcon, + cros_tokens::kCrosSysOnSurface, + kSettingsIconSizeDip)); title_container_->SetProperty(views::kMarginsKey, kTitleContainerInsets); - title_container_->SetPreferredSize( - gfx::Size(kContainerMinWidthDip - kTitleContainerInsets.width(), - title->GetPreferredSize().height())); + + int width = kContainerMinWidthDip - kTitleContainerInsets.width(); + int height = std::max(title->GetPreferredSize().height(), + settings_button_->GetPreferredSize().height()); + title_container_->SetPreferredSize(gfx::Size(width, height)); } void EditorMenuView::AddChipsContainer() {
diff --git a/chrome/browser/ui/views/editor_menu/editor_menu_view.h b/chrome/browser/ui/views/editor_menu/editor_menu_view.h index fd9f70e..54e7e3aa 100644 --- a/chrome/browser/ui/views/editor_menu/editor_menu_view.h +++ b/chrome/browser/ui/views/editor_menu/editor_menu_view.h
@@ -12,6 +12,7 @@ #include "ui/views/widget/unique_widget_ptr.h" namespace views { +class ImageButton; class FlexLayoutView; } // namespace views @@ -48,6 +49,7 @@ // Containing title, badge, and icons. raw_ptr<views::View> title_container_ = nullptr; + raw_ptr<views::ImageButton> settings_button_ = nullptr; // Containing chips. raw_ptr<views::FlexLayoutView> chips_container_ = nullptr;
diff --git a/chrome/browser/ui/views/eye_dropper/OWNERS b/chrome/browser/ui/views/eye_dropper/OWNERS index ff454c17..932bb4b0 100644 --- a/chrome/browser/ui/views/eye_dropper/OWNERS +++ b/chrome/browser/ui/views/eye_dropper/OWNERS
@@ -1,2 +1,2 @@ -iopopesc@microsoft.com +sajos@microsoft.com pkasting@chromium.org
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc index c610205..e9400d7d 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc
@@ -49,6 +49,12 @@ CookieControlsInteractiveUiTest() { https_server_ = std::make_unique<net::EmbeddedTestServer>( net::EmbeddedTestServer::TYPE_HTTPS); + + // Overriding `base::Time::Now()` to obtain a consistent X days until + // exception expiration calculation regardless of the time the test runs. + base::subtle::ScopedTimeClockOverrides time_override( + &CookieControlsInteractiveUiTest::GetReferenceTime, + /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); } ~CookieControlsInteractiveUiTest() override = default; @@ -194,11 +200,6 @@ } IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, CreateException) { - // Overriding `base::Time::Now()` to obtain a consistent X days until - // exception expiration calculation regardless of the time the test runs. - base::subtle::ScopedTimeClockOverrides time_override( - &CookieControlsInteractiveUiTest::GetReferenceTime, - /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); // Open the bubble while 3PC are blocked, re-enable them for the site, and // confirm the appropriate exception is created. BlockThirdPartyCookies(); @@ -215,11 +216,6 @@ } IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTest, RemoveException) { - // Overriding `base::Time::Now()` to obtain a consistent X days until - // exception expiration calculation regardless of the time the test runs. - base::subtle::ScopedTimeClockOverrides time_override( - &CookieControlsInteractiveUiTest::GetReferenceTime, - /*time_ticks_override=*/nullptr, /*thread_ticks_override=*/nullptr); // Open the bubble while 3PC are blocked, but the page already has an // exception. Disable 3PC for the page, and confirm the exception is removed. BlockCookiesAndSetHighConfidenceForSite();
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc index 3726dad..20d6aef0 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
@@ -13,11 +13,11 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/language/language_model_manager_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/side_panel/read_anything/read_anything_side_panel_controller_utils.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h" #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h" #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h" +#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "chrome/browser/ui/views/side_panel/side_panel_registry.h" #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h" @@ -55,14 +55,12 @@ browser->tab_strip_model()->AddObserver(this); Observe(GetActiveWebContents()); - CreateAndRegisterEntriesForExistingWebContents(browser->tab_strip_model()); } void ReadAnythingCoordinator::InitModelWithUserPrefs() { Browser* browser = &GetBrowser(); - if (!browser->profile() || !browser->profile()->GetPrefs()) { + if (!browser->profile() || !browser->profile()->GetPrefs()) return; - } // Get user's default language to check for compatible fonts. language::LanguageModel* language_model = @@ -113,16 +111,19 @@ // Read Anything as a side panel entry observer. Browser* browser = &GetBrowser(); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); - if (!browser_view) { + if (!browser_view) return; - } + SidePanelRegistry* global_registry = + SidePanelCoordinator::GetGlobalSidePanelRegistry(browser); + global_registry->Deregister( + SidePanelEntry::Key(SidePanelEntry::Id::kReadAnything)); browser->tab_strip_model()->RemoveObserver(this); Observe(nullptr); } -void ReadAnythingCoordinator::CreateAndRegisterSidePanelEntry( - SidePanelRegistry* registry) { +void ReadAnythingCoordinator::CreateAndRegisterEntry( + SidePanelRegistry* global_registry) { auto side_panel_entry = std::make_unique<SidePanelEntry>( SidePanelEntry::Id::kReadAnything, l10n_util::GetStringUTF16(IDS_READING_MODE_TITLE), @@ -131,14 +132,7 @@ base::BindRepeating(&ReadAnythingCoordinator::CreateContainerView, base::Unretained(this))); side_panel_entry->AddObserver(this); - registry->Register(std::move(side_panel_entry)); -} - -void ReadAnythingCoordinator::CreateAndRegisterEntriesForExistingWebContents( - TabStripModel* tab_strip_model) { - for (int index = 0; index < tab_strip_model->GetTabCount(); index++) { - CreateAndRegisterEntry(tab_strip_model->GetWebContentsAt(index)); - } + global_registry->Register(std::move(side_panel_entry)); } ReadAnythingController* ReadAnythingCoordinator::GetController() { @@ -220,17 +214,6 @@ TabStripModel* tab_strip_model, const TabStripModelChange& change, const TabStripSelectionChange& selection) { - if (change.type() == TabStripModelChange::Type::kInserted) { - for (const auto& inserted_tab : change.GetInsert()->contents) { - CreateAndRegisterEntry(inserted_tab.contents); - } - } - if (change.type() == TabStripModelChange::Type::kReplaced) { - raw_ptr<content::WebContents> new_contents = - change.GetReplace()->new_contents; - CHECK(new_contents); - CreateAndRegisterEntry(new_contents); - } if (!selection.active_tab_changed()) { return; }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h index 10faabd..36e7e603 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
@@ -51,7 +51,7 @@ ReadAnythingCoordinator& operator=(const ReadAnythingCoordinator&) = delete; ~ReadAnythingCoordinator() override; - void CreateAndRegisterSidePanelEntry(SidePanelRegistry* registry); + void CreateAndRegisterEntry(SidePanelRegistry* global_registry); ReadAnythingController* GetController(); ReadAnythingModel* GetModel(); @@ -64,10 +64,6 @@ friend class BrowserUserData<ReadAnythingCoordinator>; friend class ReadAnythingCoordinatorTest; - void CreateAndRegisterEntriesForExistingWebContents( - TabStripModel* tab_strip_model); - void DeregisterEntriesForExistingWebContents(TabStripModel* tab_strip_model); - // Used during construction to initialize the model with saved user prefs. void InitModelWithUserPrefs();
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc index 9310e2f..1a52e321aa 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
@@ -35,41 +35,12 @@ scoped_feature_list_.InitWithFeatures({features::kReadAnything}, {}); TestWithBrowserView::SetUp(); - // Ensure a kReadAnything entry is added to the contextual registry for the - // first tab. - AddTab(browser_view()->browser(), GURL("http://foo1.com")); - content::WebContents* active_contents = - browser_view()->GetActiveWebContents(); - auto* tab_one_registry = SidePanelRegistry::Get(active_contents); side_panel_coordinator_ = SidePanelUtil::GetSidePanelCoordinatorForBrowser(browser()); + side_panel_registry_ = + SidePanelCoordinator::GetGlobalSidePanelRegistry(browser()); read_anything_coordinator_ = ReadAnythingCoordinator::GetOrCreateForBrowser(browser()); - contextual_registries_.push_back(tab_one_registry); - - // Ensure a kReadAnything entry is added to the contextual registry for the - // second tab. - AddTab(browser_view()->browser(), GURL("http://foo2.com")); - active_contents = browser_view()->GetActiveWebContents(); - auto* tab_two_registry = SidePanelRegistry::Get(active_contents); - contextual_registries_.push_back(tab_two_registry); - - // Verify the first tab has one entry, kReadAnything. - browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); - active_contents = browser_view()->GetActiveWebContents(); - SidePanelRegistry* contextual_registry = - SidePanelRegistry::Get(active_contents); - ASSERT_EQ(contextual_registry->entries().size(), 1u); - EXPECT_EQ(contextual_registry->entries()[0]->key().id(), - SidePanelEntry::Id::kReadAnything); - - // Verify the second tab has one entry, kReadAnything. - browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); - active_contents = browser_view()->GetActiveWebContents(); - contextual_registry = SidePanelRegistry::Get(active_contents); - ASSERT_EQ(contextual_registry->entries().size(), 1u); - EXPECT_EQ(contextual_registry->entries()[0]->key().id(), - SidePanelEntry::Id::kReadAnything); } // Wrapper methods around the ReadAnythingCoordinator. These do nothing more @@ -94,8 +65,7 @@ protected: raw_ptr<SidePanelCoordinator, DanglingUntriaged> side_panel_coordinator_ = nullptr; - std::vector<raw_ptr<SidePanelRegistry, DanglingUntriaged>> - contextual_registries_; + raw_ptr<SidePanelRegistry, DanglingUntriaged> side_panel_registry_ = nullptr; raw_ptr<ReadAnythingCoordinator, DanglingUntriaged> read_anything_coordinator_ = nullptr; @@ -147,7 +117,7 @@ TEST_F(ReadAnythingCoordinatorTest, ActivateCalled_ShowAndHideReadAnythingEntry) { AddObserver(&coordinator_observer_); - SidePanelEntry* entry = contextual_registries_[0]->GetEntryForKey( + SidePanelEntry* entry = side_panel_registry_->GetEntryForKey( SidePanelEntry::Key(SidePanelEntry::Id::kReadAnything)); EXPECT_CALL(coordinator_observer_, Activate(true)).Times(1);
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_utils.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_utils.cc index ce9e732c..7f5e3798e 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_utils.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_utils.cc
@@ -4,11 +4,7 @@ #include "chrome/browser/ui/side_panel/read_anything/read_anything_side_panel_controller_utils.h" -#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/side_panel/side_panel_ui.h" -#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h" -#include "chrome/browser/ui/views/side_panel/side_panel_registry.h" -#include "content/public/browser/web_contents_observer.h" void ShowReadAnythingSidePanel(Browser* browser) { SidePanelUI* side_panel_ui = SidePanelUI::GetSidePanelUIForBrowser(browser); @@ -28,18 +24,3 @@ (side_panel_ui->GetCurrentEntryId() == SidePanelEntryId::kReadAnything); } - -void CreateAndRegisterEntry(content::WebContents* web_contents) { - auto* registry = SidePanelRegistry::Get(web_contents); - Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - CHECK(registry); - CHECK(browser); - // If the web contents is already registered to read anything, do nothing. - if (registry->GetEntryForKey( - SidePanelEntry::Key(SidePanelEntry::Id::kReadAnything))) { - return; - } - - auto* coordinator = ReadAnythingCoordinator::GetOrCreateForBrowser(browser); - coordinator->CreateAndRegisterSidePanelEntry(registry); -}
diff --git a/chrome/browser/ui/views/side_panel/side_panel_util.cc b/chrome/browser/ui/views/side_panel/side_panel_util.cc index 98c92ce1..4443ed9 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_util.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_util.cc
@@ -88,7 +88,8 @@ // Add read anything. if (features::IsReadAnythingEnabled()) { - ReadAnythingCoordinator::GetOrCreateForBrowser(browser); + ReadAnythingCoordinator::GetOrCreateForBrowser(browser) + ->CreateAndRegisterEntry(global_registry); } // Create Search Companion coordinator.
diff --git a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc index 8deb516..53857aa 100644 --- a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc
@@ -194,6 +194,7 @@ return browser_context; }, base::Unretained(profile_)), + /*storage_partition_config=*/absl::nullopt, url::Origin::Create(app_start_url_), content::ClearSiteDataTypeSet::All(), /*storage_buckets_to_remove=*/{}, /*avoid_closing_connections=*/false,
diff --git a/chrome/browser/ui/webui/management/management_ui_handler.cc b/chrome/browser/ui/webui/management/management_ui_handler.cc index 6593948..7174cbd 100644 --- a/chrome/browser/ui/webui/management/management_ui_handler.cc +++ b/chrome/browser/ui/webui/management/management_ui_handler.cc
@@ -475,7 +475,10 @@ bool report_login_logout = false; ash::CrosSettings::Get()->GetBoolean(ash::kReportDeviceLoginLogout, &report_login_logout); - if (report_login_logout) { + bool report_xdr_events = false; + ash::CrosSettings::Get()->GetBoolean(ash::kDeviceReportXDREvents, + &report_xdr_events); + if (report_login_logout || report_xdr_events) { AddDeviceReportingElement(report_sources, kManagementReportLoginLogout, DeviceReportingType::kLoginLogout); } @@ -838,15 +841,19 @@ } // Check if DeviceReportXDREvents is enabled. - auto* xdr_policy_value = GetPolicyService() - ->GetPolicies(policy::PolicyNamespace( - policy::POLICY_DOMAIN_CHROME, std::string())) - .GetValue(policy::key::kDeviceReportXDREvents, - base::Value::Type::BOOLEAN); - bool xdr_policy_enabled = xdr_policy_value && xdr_policy_value->GetBool(); + auto* report_xdr_events_policy_value = + GetPolicyService() + ->GetPolicies(policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, + std::string())) + .GetValue(policy::key::kDeviceReportXDREvents, + base::Value::Type::BOOLEAN); + bool report_xdr_events_policy_enabled = + report_xdr_events_policy_value && + report_xdr_events_policy_value->GetBool(); - if (xdr_policy_enabled) { - response->Set("showMonitoredNetworkPrivacyDisclosure", xdr_policy_enabled); + if (report_xdr_events_policy_enabled) { + response->Set("showMonitoredNetworkPrivacyDisclosure", + report_xdr_events_policy_enabled); return; }
diff --git a/chrome/browser/ui/webui/management/management_ui_handler_unittest.cc b/chrome/browser/ui/webui/management/management_ui_handler_unittest.cc index 6f2ff435..33d497db 100644 --- a/chrome/browser/ui/webui/management/management_ui_handler_unittest.cc +++ b/chrome/browser/ui/webui/management/management_ui_handler_unittest.cc
@@ -1121,7 +1121,8 @@ {kManagementExtensionReportUsername, "username"}, {kManagementReportExtensions, "extension"}, {kManagementReportAndroidApplications, "android application"}, - {kManagementReportDlpEvents, "dlp events"}}; + {kManagementReportDlpEvents, "dlp events"}, + {kManagementReportLoginLogout, "login-logout"}}; ASSERT_PRED_FORMAT2(ReportingElementsToBeEQ, info, expected_elements); } @@ -1145,7 +1146,8 @@ {kManagementCrostiniContainerConfiguration, "crostini"}, {kManagementExtensionReportUsername, "username"}, {kManagementReportExtensions, "extension"}, - {kManagementReportAndroidApplications, "android application"}}; + {kManagementReportAndroidApplications, "android application"}, + {kManagementReportLoginLogout, "login-logout"}}; ASSERT_PRED_FORMAT2(ReportingElementsToBeEQ, info, expected_elements); } @@ -1218,7 +1220,8 @@ const base::Value::List info = SetUpForReportingInfo(); const std::map<std::string, std::string> expected_elements = { {kManagementReportActivityTimes, "device activity"}, - {kManagementReportAppInfoAndActivity, "app info and activity"}}; + {kManagementReportAppInfoAndActivity, "app info and activity"}, + {kManagementReportLoginLogout, "login-logout"}}; ASSERT_PRED_FORMAT2(ReportingElementsToBeEQ, info, expected_elements); }
diff --git a/chrome/browser/ui/webui/ntp/app_resource_cache_factory.cc b/chrome/browser/ui/webui/ntp/app_resource_cache_factory.cc index 7ba759a9..98756fec 100644 --- a/chrome/browser/ui/webui/ntp/app_resource_cache_factory.cc +++ b/chrome/browser/ui/webui/ntp/app_resource_cache_factory.cc
@@ -34,7 +34,8 @@ AppResourceCacheFactory::~AppResourceCacheFactory() = default; -KeyedService* AppResourceCacheFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AppResourceCacheFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const { - return new NTPResourceCache(static_cast<Profile*>(profile)); + return std::make_unique<NTPResourceCache>(static_cast<Profile*>(profile)); }
diff --git a/chrome/browser/ui/webui/ntp/app_resource_cache_factory.h b/chrome/browser/ui/webui/ntp/app_resource_cache_factory.h index e088829..ae4bb1a 100644 --- a/chrome/browser/ui/webui/ntp/app_resource_cache_factory.h +++ b/chrome/browser/ui/webui/ntp/app_resource_cache_factory.h
@@ -27,7 +27,7 @@ ~AppResourceCacheFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; };
diff --git a/chrome/browser/ui/webui/settings/mac_system_settings_handler.cc b/chrome/browser/ui/webui/settings/mac_system_settings_handler.cc index b18d53a69..c8accb7 100644 --- a/chrome/browser/ui/webui/settings/mac_system_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/mac_system_settings_handler.cc
@@ -23,7 +23,7 @@ void MacSystemSettingsHandler::HandleOpenTrackpadGesturesSettings( const base::Value::List& args) { - DCHECK(IsJavascriptAllowed()); + AllowJavascript(); // TODO(crbug.com/1473415): Figure out how to directly open the more gestures // subpane. Currently this only opens the first subpane of trackpad settings. base::mac::OpenSystemSettingsPane(base::mac::SystemSettingsPane::kTrackpad);
diff --git a/chrome/browser/unified_consent/unified_consent_service_factory.cc b/chrome/browser/unified_consent/unified_consent_service_factory.cc index 6fb4514..66040d9 100644 --- a/chrome/browser/unified_consent/unified_consent_service_factory.cc +++ b/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -80,7 +80,8 @@ UnifiedConsentService::RegisterPrefs(registry); } -KeyedService* UnifiedConsentServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +UnifiedConsentServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); sync_preferences::PrefServiceSyncable* pref_service = @@ -93,7 +94,7 @@ if (!sync_service) return nullptr; - return new UnifiedConsentService( + return std::make_unique<UnifiedConsentService>( pref_service, IdentityManagerFactory::GetForProfile(profile), sync_service, GetSyncedServicePrefNames()); }
diff --git a/chrome/browser/unified_consent/unified_consent_service_factory.h b/chrome/browser/unified_consent/unified_consent_service_factory.h index 4cd6a02..8a8ed755 100644 --- a/chrome/browser/unified_consent/unified_consent_service_factory.h +++ b/chrome/browser/unified_consent/unified_consent_service_factory.h
@@ -36,7 +36,7 @@ ~UnifiedConsentServiceFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* profile) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/user_notes/user_note_service_factory.cc b/chrome/browser/user_notes/user_note_service_factory.cc index 3a2808f4..c763257 100644 --- a/chrome/browser/user_notes/user_note_service_factory.cc +++ b/chrome/browser/user_notes/user_note_service_factory.cc
@@ -56,10 +56,11 @@ UserNoteServiceFactory::~UserNoteServiceFactory() = default; -KeyedService* UserNoteServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +UserNoteServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { DCHECK(IsUserNotesEnabled()); - return new UserNoteService( + return std::make_unique<UserNoteService>( std::make_unique<UserNoteServiceDelegateImpl>( Profile::FromBrowserContext(context)), std::make_unique<UserNoteStorageImpl>(context->GetPath()));
diff --git a/chrome/browser/user_notes/user_note_service_factory.h b/chrome/browser/user_notes/user_note_service_factory.h index 67935fa..388dc63f 100644 --- a/chrome/browser/user_notes/user_note_service_factory.h +++ b/chrome/browser/user_notes/user_note_service_factory.h
@@ -41,7 +41,7 @@ ~UserNoteServiceFactory() override; // BrowserContextKeyedServiceFactory implementation. - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; raw_ptr<UserNoteService> service_for_testing_;
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index 415c6fa..027be4c 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -840,7 +840,8 @@ return browser_context; }, base::Unretained(profile())), - origin, content::ClearSiteDataTypeSet::All(), + /*storage_partition_config=*/absl::nullopt, origin, + content::ClearSiteDataTypeSet::All(), /*storage_buckets_to_remove=*/{}, /*avoid_closing_connections=*/false, /*cookie_partition_key=*/absl::nullopt, /*storage_key=*/absl::nullopt,
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index f9171f3..7c72f82 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1692705406-2569e9c2ba6940188a2f9ead902b7f1fa42da23f.profdata +chrome-android32-main-1692727167-dc84bea84ee06c549525c89af7566751f980169a.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 3b53844a..5d03925 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1692705406-bd090c958d43221789f3cce549ed0dda8fc96fe5.profdata +chrome-android64-main-1692727167-55886d71ecef8bda4393c4413b8017b9ff68c0f2.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 0bcab99..453df0e2 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1692705406-230dc31b2a3853951268a262e70d185d54d282c1.profdata +chrome-linux-main-1692727167-a75b067add08f6ba64a5e7f9bed5dddadbff3736.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 0ff5be2..68e35fe 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1692719993-3a0a46be97bbb4411240cb357cc445df49e8248c.profdata +chrome-mac-arm-main-1692734385-f8b5079f20fb00dbba55ed2baea8500132f74f1e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 6501241..e36584a 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1692705406-2b442492e7dabe489cdb4d988c44814edc4971da.profdata +chrome-mac-main-1692727167-7eae91b2022c958f699cbeb318c3d1a0b89d5570.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index f379dfd..d758a922 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1692705406-707d6189eb5b4f5b33eb76c97b0c0bc235eb11cb.profdata +chrome-win32-main-1692716378-0dce133d23bbd3396bff61bb3ae7375c8ca78a31.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index be09c2c..1288bc5c 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1692705406-0b0f6754db54de403883810fce139537f583490c.profdata +chrome-win64-main-1692727167-c621730366ff87856ecd365d1b271cfe13482c28.profdata
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json index 83b1439..07f7899 100644 --- a/chrome/common/extensions/api/accessibility_private.json +++ b/chrome/common/extensions/api/accessibility_private.json
@@ -293,6 +293,13 @@ } }, { + "id": "ToastType", + "type": "string", + "enum": [ + "dictationNoFocusedTextField" + ] + }, + { "id": "DlcType", "type": "string", "enum": [ @@ -894,6 +901,16 @@ } ] } + }, + { + "name": "showToast", + "type": "function", + "description": "Displays an accessibility-related toast.", + "parameters": [{ + "name": "type", + "$ref": "ToastType", + "description": "The type of toast to show." + }] } ], "events": [
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index d4d7c57..ff20dec1 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1864,18 +1864,6 @@ "side_panel.google_search_side_panel_enabled"; #endif -// Number of minutes of inactivity before running actions from -// kIdleTimeoutActions. Controlled via the IdleTimeout policy. -inline constexpr char kIdleTimeout[] = "idle_timeout"; - -// Actions to run when the idle timeout is reached. Controller via the -// IdleTimeoutActions policy. -inline constexpr char kIdleTimeoutActions[] = "idle_timeout_actions"; - -// If true, show the IdleTimeout bubble when Chrome starts. -inline constexpr char kIdleTimeoutShowBubbleOnStartup[] = - "idle_timeout_show_bubble_on_startup"; - // *************** LOCAL STATE *************** // These are attached to the machine/installation
diff --git a/chrome/services/sharing/nearby/nearby_presence_conversions.cc b/chrome/services/sharing/nearby/nearby_presence_conversions.cc index 275fd17..6b0a294 100644 --- a/chrome/services/sharing/nearby/nearby_presence_conversions.cc +++ b/chrome/services/sharing/nearby/nearby_presence_conversions.cc
@@ -150,8 +150,8 @@ shared_credential.encrypted_metadata_bytes_v0().begin(), shared_credential.encrypted_metadata_bytes_v0().end()), std::vector<uint8_t>( - shared_credential.metadata_encryption_key_unsigned_adv_tag().begin(), - shared_credential.metadata_encryption_key_unsigned_adv_tag().end()), + shared_credential.metadata_encryption_key_tag_v0().begin(), + shared_credential.metadata_encryption_key_tag_v0().end()), std::vector<uint8_t>( shared_credential.connection_signature_verification_key().begin(), shared_credential.connection_signature_verification_key().end()), @@ -175,7 +175,7 @@ proto.set_encrypted_metadata_bytes_v0( std::string(shared_credential->encrypted_metadata_bytes.begin(), shared_credential->encrypted_metadata_bytes.end())); - proto.set_metadata_encryption_key_unsigned_adv_tag( + proto.set_metadata_encryption_key_tag_v0( std::string(shared_credential->metadata_encryption_key_tag.begin(), shared_credential->metadata_encryption_key_tag.end())); proto.set_connection_signature_verification_key(std::string(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ceece5d..7aa0a83 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -9163,8 +9163,8 @@ sources += [ "../browser/enterprise/idle/action_runner_unittest.cc", "../browser/enterprise/idle/action_unittest.cc", - "../browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc", ] + deps += [ "//components/enterprise/idle" ] } if (is_linux || is_mac || is_win) { @@ -10864,6 +10864,8 @@ "../browser/ui/views/profiles/first_run_interactive_uitest.cc", "../browser/ui/views/profiles/profile_bubble_interactive_uitest.cc", ] + + deps += [ "//components/enterprise/idle" ] } if (enable_print_preview) {
diff --git a/chrome/test/data/extensions/api_test/user_scripts/get_scripts/empty.js b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/empty.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/empty.js
diff --git a/chrome/test/data/extensions/api_test/user_scripts/get_scripts/empty2.js b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/empty2.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/empty2.js
diff --git a/chrome/test/data/extensions/api_test/user_scripts/get_scripts/manifest.json b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/manifest.json new file mode 100644 index 0000000..9f1373d --- /dev/null +++ b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/manifest.json
@@ -0,0 +1,14 @@ +{ + "name": "User script test extension", + "version": "0.1", + "manifest_version": 3, + "description": "Tests a variety of user scripts API calls for retrieving registered user scripts.", + "background": { + "service_worker": "worker.js", + "type": "module" + }, + "permissions": [ + "userScripts", + "scripting" + ] +} \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/user_scripts/get_scripts/worker.js b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/worker.js new file mode 100644 index 0000000..1d9023ff --- /dev/null +++ b/chrome/test/data/extensions/api_test/user_scripts/get_scripts/worker.js
@@ -0,0 +1,94 @@ +// 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. + +chrome.test.runTests([ + + // Tests that calling getScripts with no filter returns all user scripts. + async function getScripts_NoFilter() { + const userScriptsToRegister = [ + { + id: 'script1', + matches: ['*://*/*'], + excludeMatches: ['*://abc.com/*'], + allFrames: true, + js: [{file: 'empty.js'}] + }, + { + id: 'script2', + matches: ['*://requested.com/*'], + js: [{file: 'empty2.js'}], + runAt: 'document_end' + } + ]; + + const contentScriptsToRegister = + [{id: 'contentScript', matches: ['*://*/*'], js: ['empty.js']}]; + + // Some fields are populated with their default values, and file paths are + // normalized. + const expectedUserScripts = [ + { + id: 'script1', + matches: ['*://*/*'], + excludeMatches: ['*://abc.com/*'], + allFrames: true, + js: [{file: 'empty.js'}], + runAt: 'document_idle' + }, + { + id: 'script2', + matches: ['*://requested.com/*'], + js: [{file: 'empty2.js'}], + allFrames: false, + runAt: 'document_end' + } + + ]; + + await chrome.userScripts.register(userScriptsToRegister); + await chrome.scripting.registerContentScripts(contentScriptsToRegister); + + // Calling getScripts with no filter returns all user scripts. + let scripts = await chrome.userScripts.getScripts(); + chrome.test.assertEq(expectedUserScripts, scripts); + + // Calling getScripts with an empty filter returns all user scripts. + scripts = await chrome.userScripts.getScripts({}); + chrome.test.assertEq(expectedUserScripts, scripts); + + // Calling getScripts with empty ids in filter returns no scripts. + // TODO(crbug.com/385165): Move to its separate test after implementing + // userScripts.unregister(), so we can unregister scripts in between tests. + scripts = await chrome.userScripts.getScripts({ids: []}); + chrome.test.assertEq([], scripts); + + chrome.test.succeed(); + }, + + // Tests that calling getScripts with a given filter returns only scripts + // matching the filter. + async function getScripts_Filter() { + const scriptsToRegister = [ + {id: 'script3', matches: ['*://*/*'], js: [{file: 'empty.js'}]}, + {id: 'script4', matches: ['*://*/*'], js: [{file: 'empty2.js'}]} + ]; + + const expectedScripts = [{ + id: 'script3', + matches: ['*://*/*'], + allFrames: false, + js: [{file: 'empty.js'}], + runAt: 'document_idle' + }]; + + await chrome.userScripts.register(scriptsToRegister); + + let scripts = + await chrome.userScripts.getScripts({ids: ['script3', 'nonExistent']}); + chrome.test.assertEq(expectedScripts, scripts); + + chrome.test.succeed(); + }, + +]);
diff --git a/chrome/test/data/extensions/api_test/user_scripts/manifest.json b/chrome/test/data/extensions/api_test/user_scripts/register/manifest.json similarity index 100% rename from chrome/test/data/extensions/api_test/user_scripts/manifest.json rename to chrome/test/data/extensions/api_test/user_scripts/register/manifest.json
diff --git a/chrome/test/data/extensions/api_test/user_scripts/script.js b/chrome/test/data/extensions/api_test/user_scripts/register/script.js similarity index 100% rename from chrome/test/data/extensions/api_test/user_scripts/script.js rename to chrome/test/data/extensions/api_test/user_scripts/register/script.js
diff --git a/chrome/test/data/extensions/api_test/user_scripts/worker.js b/chrome/test/data/extensions/api_test/user_scripts/register/worker.js similarity index 97% rename from chrome/test/data/extensions/api_test/user_scripts/worker.js rename to chrome/test/data/extensions/api_test/user_scripts/register/worker.js index f6005476..9c69059 100644 --- a/chrome/test/data/extensions/api_test/user_scripts/worker.js +++ b/chrome/test/data/extensions/api_test/user_scripts/register/worker.js
@@ -239,7 +239,9 @@ await chrome.scripting.getRegisteredContentScripts(); chrome.test.assertEq('contentScript', registered_content_scripts[0].id); // TODO(crbug.com/1385165): Assert user script was registered once we add - // a User Scripts API method for retrieving user scripts. + // a User Scripts API method for retrieving user scripts and unregistering + // them in between tests (otherwise we would retrieve here all user scripts + // across tests). chrome.test.succeed(); },
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts index 3a190a8..9a45ce7f 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
@@ -16,7 +16,7 @@ import {fakeAcceleratorConfig, fakeDefaultAccelerators, fakeLayoutInfo} from 'chrome://shortcut-customization/js/fake_data.js'; import {FakeShortcutProvider} from 'chrome://shortcut-customization/js/fake_shortcut_provider.js'; import {setShortcutProviderForTesting} from 'chrome://shortcut-customization/js/mojo_interface_provider.js'; -import {Accelerator, AcceleratorConfigResult, AcceleratorInfo, AcceleratorState, Modifier} from 'chrome://shortcut-customization/js/shortcut_types.js'; +import {Accelerator, AcceleratorConfigResult, AcceleratorInfo, AcceleratorKeyState, AcceleratorState, Modifier} from 'chrome://shortcut-customization/js/shortcut_types.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'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -310,6 +310,7 @@ const defaultAccelerators: Accelerator[] = [{ modifiers: Modifier.CONTROL | Modifier.SHIFT, keyCode: 71, + keyState: AcceleratorKeyState.PRESSED, }]; provider.setFakeGetDefaultAcceleratorsForId(defaultAccelerators); @@ -678,6 +679,7 @@ const defaultAccelerators: Accelerator[] = [{ modifiers: Modifier.CONTROL | Modifier.SHIFT, keyCode: 71, + keyState: AcceleratorKeyState.PRESSED, }]; provider.setFakeGetDefaultAcceleratorsForId(defaultAccelerators); @@ -790,7 +792,11 @@ const acceleratorInfo5: AcceleratorInfo = createAliasedStandardAcceleratorInfo( Modifier.CONTROL, /*key=*/ 67, /*keyDisplay=*/ 'c', - AcceleratorState.kEnabled, {modifiers: Modifier.ALT, keyCode: 67}); + AcceleratorState.kEnabled, { + modifiers: Modifier.ALT, + keyCode: 67, + keyState: AcceleratorKeyState.PRESSED, + }); // Initialize with max accelerators. const accelerators = [
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts index 15be694..5a643aa 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_lookup_manager_test.ts
@@ -7,7 +7,7 @@ import {AcceleratorLookupManager} from 'chrome://shortcut-customization/js/accelerator_lookup_manager.js'; import {fakeAcceleratorConfig, fakeAmbientConfig, fakeLayoutInfo} from 'chrome://shortcut-customization/js/fake_data.js'; import {FakeShortcutProvider} from 'chrome://shortcut-customization/js/fake_shortcut_provider.js'; -import {Accelerator, AcceleratorCategory, AcceleratorSource, AcceleratorState, Modifier, MojoAccelerator, MojoAcceleratorInfo, StandardAcceleratorInfo} from 'chrome://shortcut-customization/js/shortcut_types.js'; +import {Accelerator, AcceleratorCategory, AcceleratorKeyState, AcceleratorSource, AcceleratorState, Modifier, MojoAccelerator, MojoAcceleratorInfo, StandardAcceleratorInfo} from 'chrome://shortcut-customization/js/shortcut_types.js'; import {areAcceleratorsEqual, createEmptyAccelInfoFromAccel} from 'chrome://shortcut-customization/js/shortcut_utils.js'; import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -134,6 +134,7 @@ const expectedNewAccel: Accelerator = { modifiers: Modifier.CONTROL, keyCode: 79, + keyState: AcceleratorKeyState.PRESSED, }; // Sanity check that new accel is not in the reverse lookup. @@ -159,6 +160,7 @@ const expectedNewDefaultAccel: Accelerator = { modifiers: Modifier.ALT, keyCode: 221, + keyState: AcceleratorKeyState.PRESSED, }; // Sanity check that new accel is not in the reverse lookup. @@ -238,6 +240,7 @@ const expectedNewAccel: Accelerator = { modifiers: Modifier.CONTROL, keyCode: 79, + keyState: AcceleratorKeyState.PRESSED, }; // Sanity check that new accel is not in the reverse lookup. @@ -351,6 +354,7 @@ const expectedNewAccel: Accelerator = { modifiers: Modifier.CONTROL, keyCode: 79, + keyState: AcceleratorKeyState.PRESSED, }; // Sanity check that new accel is not in the reverse lookup.
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts index 4b28c83..a8c78d9 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test_util.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 {Accelerator, AcceleratorState, AcceleratorType, StandardAcceleratorInfo, TextAcceleratorInfo, TextAcceleratorPart} from 'chrome://shortcut-customization/js/shortcut_types.js'; +import {Accelerator, AcceleratorKeyState, AcceleratorState, AcceleratorType, StandardAcceleratorInfo, TextAcceleratorInfo, TextAcceleratorPart} from 'chrome://shortcut-customization/js/shortcut_types.js'; export function createStandardAcceleratorInfo( @@ -15,6 +15,7 @@ accelerator: { modifiers: modifier, keyCode: keycode, + keyState: AcceleratorKeyState.PRESSED, }, }, }, @@ -48,6 +49,7 @@ accelerator: { modifiers: modifier, keyCode: keycode, + keyState: AcceleratorKeyState.PRESSED, }, }, }, @@ -67,6 +69,7 @@ accelerator: { modifiers: modifier, keyCode: keycode, + keyState: AcceleratorKeyState.PRESSED, }, }, }, @@ -87,6 +90,7 @@ accelerator: { modifiers: modifier, keyCode: keyCode, + keyState: AcceleratorKeyState.PRESSED, }, originalAccelerator: originalAccelerator, },
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts index b12548c..e8ce8cc 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_utils_test.ts
@@ -7,7 +7,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {stringToMojoString16} from 'chrome://resources/js/mojo_type_util.js'; import {CycleTabsTextSearchResult, SnapWindowLeftSearchResult, TakeScreenshotSearchResult} from 'chrome://shortcut-customization/js/fake_data.js'; -import {Accelerator, AcceleratorCategory, Modifier, MojoAccelerator, StandardAcceleratorInfo, TextAcceleratorPart, TextAcceleratorPartType} from 'chrome://shortcut-customization/js/shortcut_types.js'; +import {Accelerator, AcceleratorCategory, AcceleratorKeyState, Modifier, MojoAccelerator, StandardAcceleratorInfo, TextAcceleratorPart, TextAcceleratorPartType} from 'chrome://shortcut-customization/js/shortcut_types.js'; import {areAcceleratorsEqual, compareAcceleratorInfos, getAccelerator, getAcceleratorId, getModifiersForAcceleratorInfo, getModifierString, getSortedModifiers, getSourceAndActionFromAcceleratorId, getURLForSearchResult, isCustomizationDisabled, isSearchEnabled, isStandardAcceleratorInfo, isTextAcceleratorInfo, SHORTCUTS_APP_URL} from 'chrome://shortcut-customization/js/shortcut_utils.js'; import {assertArrayEquals, assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -60,6 +60,7 @@ const accelShiftC: Accelerator = { modifiers: Modifier.SHIFT, keyCode: 67, // c + keyState: AcceleratorKeyState.PRESSED, }; const accelShiftCCopy: Accelerator = { ...accelShiftC, @@ -67,10 +68,12 @@ const accelAltC: Accelerator = { modifiers: Modifier.ALT, keyCode: 67, // c + keyState: AcceleratorKeyState.PRESSED, }; const accelShiftD: Accelerator = { modifiers: Modifier.SHIFT, keyCode: 68, // d + keyState: AcceleratorKeyState.PRESSED, }; // Compare the same accelerator. @@ -90,6 +93,7 @@ const accelShiftC: Accelerator = { modifiers: Modifier.SHIFT, keyCode: 67, // c + keyState: AcceleratorKeyState.PRESSED, }; const accelShiftCMojo: MojoAccelerator = { modifiers: Modifier.SHIFT, @@ -133,6 +137,7 @@ const expectedAccelerator: Accelerator = { modifiers: Modifier.ALT, keyCode: 221, // c + keyState: AcceleratorKeyState.PRESSED, }; const actualAccelerator = getAccelerator(acceleratorInfo); assertDeepEquals(expectedAccelerator, actualAccelerator);
diff --git a/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts index 9234ee8..bea2c5c 100644 --- a/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts +++ b/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts
@@ -114,8 +114,8 @@ assertTrue(!!headerElement); const label = $$(headerElement, '#label'); assertTrue(!!label); - assertModuleHeaderTitle(label as HTMLElement, `${sampleClusterLabel}`); + assertTrue(!!$$(headerElement, 'ntp-module-header-v2')); }); test('Header info button click opens info dialog', async () => { @@ -170,7 +170,8 @@ const dismissButton = moduleElement.shadowRoot! .querySelector('history-clusters-header-v2')!.shadowRoot! - .querySelector<HTMLElement>('#dismiss')!; + .querySelector('ntp-module-header-v2')!.shadowRoot! + .querySelector('#dismiss')! as HTMLButtonElement; dismissButton.click(); // Assert. @@ -207,7 +208,8 @@ const doneButton = moduleElement.shadowRoot! .querySelector('history-clusters-header-v2')!.shadowRoot! - .querySelector<HTMLElement>('#done')!; + .querySelector('ntp-module-header-v2')!.shadowRoot! + .querySelector('#done')! as HTMLButtonElement; doneButton.click(); // Assert.
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/customize_button_row_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/customize_button_row_test.ts index c6bb9aa2..61bdd69 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/customize_button_row_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/customize_button_row_test.ts
@@ -62,10 +62,10 @@ expectedRemapping!.remappingAction?.action!.toString()); // Change buttonRemapping data to display. + customizeButtonRow.set('remappingIndex', 1); customizeButtonRow.set( 'buttonRemappingList', fakeGraphicsTablets[1]!.settings.tabletButtonRemappings); - customizeButtonRow.set('remappingIndex', 1); await flushTasks(); expectedRemapping = fakeGraphicsTablets[1]!.settings.tabletButtonRemappings[1]; @@ -77,4 +77,26 @@ getSelectedValue(), expectedRemapping!.remappingAction?.action!.toString()); }); + + test('Initialize key combination string', async () => { + await initializeCustomizeButtonRow(); + customizeButtonRow.set( + 'buttonRemappingList', + fakeGraphicsTablets[0]!.settings.penButtonRemappings); + customizeButtonRow.set('remappingIndex', 0); + await flushTasks(); + + assertEquals(getSelectedValue(), 'key combination'); + assertEquals(customizeButtonRow.get('keyCombinationLabel_'), 'ctrl + z'); + + // Switch to another button remapping. + customizeButtonRow.set( + 'buttonRemappingList', + fakeGraphicsTablets[1]!.settings.penButtonRemappings); + customizeButtonRow.set('remappingIndex', 1); + await flushTasks(); + + assertEquals(getSelectedValue(), 'key combination'); + assertEquals(customizeButtonRow.get('keyCombinationLabel_'), 'ctrl + v'); + }); });
diff --git a/chrome/updater/ipc/proxy_impl_base_win.h b/chrome/updater/ipc/proxy_impl_base_win.h index 5428a49..ed9edb57 100644 --- a/chrome/updater/ipc/proxy_impl_base_win.h +++ b/chrome/updater/ipc/proxy_impl_base_win.h
@@ -51,6 +51,9 @@ protected: explicit ProxyImplBase(UpdaterScope scope) : scope_(scope) { DETACH_FROM_SEQUENCE(sequence_checker_); + VLOG(2) << __func__; + // TODO(crbug.com/1473487): remove after the issue is resolved. + task_runner_->PostTask(FROM_HERE, base::BindOnce([] { ExpectIsSTA(); })); } ~ProxyImplBase() { @@ -59,10 +62,9 @@ } void PostRPCTask(base::OnceClosure task) { - // TODO(crbug.com/1473487): replace with CHECK. - task_runner_->PostTask(FROM_HERE, base::BindOnce([] { - DUMP_WILL_BE_CHECK(IsSTA()); - }).Then(std::move(task))); + // TODO(crbug.com/1473487): replace expectation with a CHECK. + task_runner_->PostTask( + FROM_HERE, base::BindOnce([] { ExpectIsSTA(); }).Then(std::move(task))); } HResultOr<Microsoft::WRL::ComPtr<Interface>> CreateInterface() const {
diff --git a/chrome/updater/util/win_util.cc b/chrome/updater/util/win_util.cc index c6a98b73b..78861974 100644 --- a/chrome/updater/util/win_util.cc +++ b/chrome/updater/util/win_util.cc
@@ -26,6 +26,7 @@ #include "base/containers/cxx20_erase.h" #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" +#include "base/debug/alias.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/functional/callback_helpers.h" @@ -1057,4 +1058,17 @@ (apt_type == APTTYPE_STA || apt_type == APTTYPE_MAINSTA); } +void ExpectIsSTA() { + VLOG(2) << __func__; + HRESULT hr = S_OK; + base::debug::Alias(&hr); + APTTYPE apt_type = APTTYPE_CURRENT; + base::debug::Alias(&apt_type); + APTTYPEQUALIFIER apt_type_qualifier = APTTYPEQUALIFIER_NONE; + base::debug::Alias(&apt_type_qualifier); + hr = ::CoGetApartmentType(&apt_type, &apt_type_qualifier); + DUMP_WILL_BE_CHECK(SUCCEEDED(hr) && + (apt_type == APTTYPE_STA || apt_type == APTTYPE_MAINSTA)); +} + } // namespace updater
diff --git a/chrome/updater/util/win_util.h b/chrome/updater/util/win_util.h index ed9623d7..e501659 100644 --- a/chrome/updater/util/win_util.h +++ b/chrome/updater/util/win_util.h
@@ -411,6 +411,9 @@ // is not a form of STA. [[nodiscard]] bool IsSTA(); +// Expects the code is running in an STA or dumps without crashing. +void ExpectIsSTA(); + } // namespace updater #endif // CHROME_UPDATER_UTIL_WIN_UTIL_H_
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java index 0bececb..5124293 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -182,6 +182,20 @@ }); }); + mCreatedState.subscribe(x -> { + IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT); + return new BroadcastReceiverScope(filter, (Intent intent) -> { + if (DEBUG) { + Log.d(TAG, "ACTION_USER_PRESENT received. canUsePictureInPicture: " + + canUsePictureInPicture() + " mAllowPictureInPicture: " + + mAllowPictureInPicture); + } + if (canUsePictureInPicture() && mAllowPictureInPicture) { + enterPictureInPictureMode(new PictureInPictureParams.Builder().build()); + } + }); + }); + Observable<Unit> shouldKeepScreenOn = mGotIntentState .filter(intent
diff --git a/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java b/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java index 91018ddd..7da1037 100644 --- a/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java +++ b/chromecast/browser/android/junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java
@@ -545,6 +545,38 @@ } @Test + @Config(shadows = {ExtendedShadowActivity.class}) + public void testEntersPipWhenAllowPipIsTrueOnUserPresent() { + mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE, true); + mActivityLifecycle.create().start().resume(); + + CastWebContentsIntentUtils.getLocalBroadcastManager().sendBroadcastSync( + CastWebContentsIntentUtils.allowPictureInPicture(mSessionId, true)); + RuntimeEnvironment.application.sendBroadcast(new Intent(Intent.ACTION_USER_PRESENT)); + + ExtendedShadowActivity shadowActivity = (ExtendedShadowActivity) Shadow.extract(mActivity); + Shadows.shadowOf(getMainLooper()).idle(); + + assertTrue(shadowActivity.getInPictureInPictureMode()); + } + + @Test + @Config(shadows = {ExtendedShadowActivity.class}) + public void testDoesNotenterPipWhenAllowPipIsFalseOnUserPresent() { + mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE, true); + mActivityLifecycle.create().start().resume(); + + CastWebContentsIntentUtils.getLocalBroadcastManager().sendBroadcastSync( + CastWebContentsIntentUtils.allowPictureInPicture(mSessionId, false)); + RuntimeEnvironment.application.sendBroadcast(new Intent(Intent.ACTION_USER_PRESENT)); + + ExtendedShadowActivity shadowActivity = (ExtendedShadowActivity) Shadow.extract(mActivity); + Shadows.shadowOf(getMainLooper()).idle(); + + assertFalse(shadowActivity.getInPictureInPictureMode()); + } + + @Test public void testSurfaceAvailable() { Observer<Unit> observer = mock(Observer.class); Scope scope = mock(Scope.class);
diff --git a/chromeos/ash/components/nearby/presence/conversions/proto_conversions.cc b/chromeos/ash/components/nearby/presence/conversions/proto_conversions.cc index 86d250c5..9e488f1 100644 --- a/chromeos/ash/components/nearby/presence/conversions/proto_conversions.cc +++ b/chromeos/ash/components/nearby/presence/conversions/proto_conversions.cc
@@ -104,7 +104,7 @@ proto.set_encrypted_metadata_bytes_v0( std::string(shared_credential->encrypted_metadata_bytes.begin(), shared_credential->encrypted_metadata_bytes.end())); - proto.set_metadata_encryption_key_unsigned_adv_tag( + proto.set_metadata_encryption_key_tag_v0( std::string(shared_credential->metadata_encryption_key_tag.begin(), shared_credential->metadata_encryption_key_tag.end())); proto.set_connection_signature_verification_key(std::string( @@ -189,8 +189,8 @@ shared_credential.encrypted_metadata_bytes_v0().begin(), shared_credential.encrypted_metadata_bytes_v0().end()), std::vector<uint8_t>( - shared_credential.metadata_encryption_key_unsigned_adv_tag().begin(), - shared_credential.metadata_encryption_key_unsigned_adv_tag().end()), + shared_credential.metadata_encryption_key_tag_v0().begin(), + shared_credential.metadata_encryption_key_tag_v0().end()), std::vector<uint8_t>( shared_credential.connection_signature_verification_key().begin(), shared_credential.connection_signature_verification_key().end()), @@ -239,7 +239,7 @@ certificate.set_encrypted_metadata_bytes( shared_credential.encrypted_metadata_bytes_v0()); certificate.set_metadata_encryption_key_tag( - shared_credential.metadata_encryption_key_unsigned_adv_tag()); + shared_credential.metadata_encryption_key_tag_v0()); certificate.set_trust_type( TrustTypeFromIdentityType(shared_credential.identity_type())); return certificate; @@ -276,7 +276,7 @@ SecondsToMilliseconds(certificate.end_time().seconds())); shared_credential.set_encrypted_metadata_bytes_v0( certificate.encrypted_metadata_bytes()); - shared_credential.set_metadata_encryption_key_unsigned_adv_tag( + shared_credential.set_metadata_encryption_key_tag_v0( certificate.metadata_encryption_key_tag()); shared_credential.set_identity_type( TrustTypeToIdentityType(certificate.trust_type()));
diff --git a/chromeos/ash/components/nearby/presence/conversions/proto_conversions_unittest.cc b/chromeos/ash/components/nearby/presence/conversions/proto_conversions_unittest.cc index c682218..b9835a3 100644 --- a/chromeos/ash/components/nearby/presence/conversions/proto_conversions_unittest.cc +++ b/chromeos/ash/components/nearby/presence/conversions/proto_conversions_unittest.cc
@@ -139,7 +139,7 @@ proto_cred.encrypted_metadata_bytes_v0()); EXPECT_EQ( std::string(kMetadataEncryptionTag.begin(), kMetadataEncryptionTag.end()), - proto_cred.metadata_encryption_key_unsigned_adv_tag()); + proto_cred.metadata_encryption_key_tag_v0()); EXPECT_EQ(std::string(kConnectionSignatureVerificationKey.begin(), kConnectionSignatureVerificationKey.end()), proto_cred.connection_signature_verification_key()); @@ -161,7 +161,7 @@ shared_credential.set_end_time_millis(kEndTimeMillis_BeforeConversion); shared_credential.set_encrypted_metadata_bytes_v0(std::string( kEncryptedMetadataBytes.begin(), kEncryptedMetadataBytes.end())); - shared_credential.set_metadata_encryption_key_unsigned_adv_tag(std::string( + shared_credential.set_metadata_encryption_key_tag_v0(std::string( kMetadataEncryptionTag.begin(), kMetadataEncryptionTag.end())); shared_credential.set_connection_signature_verification_key( std::string(kConnectionSignatureVerificationKey.begin(), @@ -228,7 +228,7 @@ proto_cred.encrypted_metadata_bytes_v0()); EXPECT_EQ( std::string(kMetadataEncryptionTag.begin(), kMetadataEncryptionTag.end()), - proto_cred.metadata_encryption_key_unsigned_adv_tag()); + proto_cred.metadata_encryption_key_tag_v0()); EXPECT_EQ(::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE, proto_cred.identity_type()); }
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc index 4cb2c09..32c31d232 100644 --- a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.cc
@@ -19,7 +19,6 @@ #include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_server_client.h" #include "chromeos/ash/components/nearby/presence/credentials/nearby_presence_server_client_impl.h" #include "chromeos/ash/components/nearby/presence/credentials/prefs.h" -#include "chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h" #include "chromeos/ash/components/nearby/presence/proto/list_public_certificates_rpc.pb.h" #include "chromeos/ash/components/nearby/presence/proto/rpc_resources.pb.h" #include "chromeos/ash/components/nearby/presence/proto/update_device_rpc.pb.h" @@ -261,6 +260,8 @@ // 4. Download other devices' credentials. // 5. Save other devices' credentials. + first_time_server_registration_attempts_needed_count_++; + // Construct a request for first time registration to let the server know // to return the user's name and image url. ash::nearby::proto::UpdateDeviceRequest request; @@ -289,14 +290,25 @@ weak_ptr_factory_.GetWeakPtr())); } -void NearbyPresenceCredentialManagerImpl::HandleFirstTimeRegistrationTimeout() { - // TODO(b/276307539): Add metrics to record the timeout. - HandleFirstTimeRegistrationFailure(); +void NearbyPresenceCredentialManagerImpl::OnFirstTimeRegistrationComplete( + metrics::FirstTimeRegistrationResult result) { + // TODO(b/288443930): Log the result when CD_LOG is implemented. + metrics::RecordFirstTimeRegistrationFlowResult(result); + CHECK(on_registered_callback_); + std::move(on_registered_callback_) + .Run(/*success=*/(result == + metrics::FirstTimeRegistrationResult::kSuccess)); } -void NearbyPresenceCredentialManagerImpl::HandleFirstTimeRegistrationFailure() { - // TODO(b/276307539): Add metrics to record failures. +void NearbyPresenceCredentialManagerImpl::HandleFirstTimeRegistrationTimeout() { + HandleFirstTimeRegistrationFailure( + /*result=*/ash::nearby::NearbyHttpResult::kTimeout); +} + +void NearbyPresenceCredentialManagerImpl::HandleFirstTimeRegistrationFailure( + ash::nearby::NearbyHttpResult result) { server_client_.reset(); + metrics::RecordFirstTimeServerRegistrationFailureReason(result); // Allow the scheduler to exponentially attempt first time registration // until the max. Once it reaches the max attempts, notify consumers of @@ -311,14 +323,19 @@ // We've exceeded the max attempts; registration has failed. first_time_registration_on_demand_scheduler_->Stop(); first_time_registration_on_demand_scheduler_.reset(); - CHECK(on_registered_callback_); - std::move(on_registered_callback_).Run(/*success=*/false); + first_time_server_registration_attempts_needed_count_ = 0; + OnFirstTimeRegistrationComplete( + metrics::FirstTimeRegistrationResult::kRegistrationWithServerFailure); } void NearbyPresenceCredentialManagerImpl::OnRegistrationRpcSuccess( const ash::nearby::proto::UpdateDeviceResponse& response) { server_response_timer_.Stop(); first_time_registration_on_demand_scheduler_->HandleResult(/*success=*/true); + metrics::RecordFirstTimeServerRegistrationTotalAttemptsNeededCount( + /*attempt_count=*/ + first_time_server_registration_attempts_needed_count_); + first_time_server_registration_attempts_needed_count_ = 0; server_client_.reset(); // Persist responses to be used to generate credentials. @@ -342,18 +359,17 @@ void NearbyPresenceCredentialManagerImpl::OnRegistrationRpcFailure( ash::nearby::NearbyHttpError error) { - // TODO(b/276307539): Add metrics to record the type of NearbyHttpError. server_response_timer_.Stop(); - HandleFirstTimeRegistrationFailure(); + HandleFirstTimeRegistrationFailure( + /*result=*/ash::nearby::NearbyHttpErrorToResult(error)); } void NearbyPresenceCredentialManagerImpl::OnFirstTimeCredentialsGenerated( std::vector<mojom::SharedCredentialPtr> shared_credentials, mojom::StatusCode status) { if (status != mojom::StatusCode::kOk) { - // TODO(b/276307539): Add metrics to record failures. - CHECK(on_registered_callback_); - std::move(on_registered_callback_).Run(/*success=*/false); + OnFirstTimeRegistrationComplete(metrics::FirstTimeRegistrationResult:: + kLocalCredentialGenerationFailure); return; } @@ -386,7 +402,8 @@ void NearbyPresenceCredentialManagerImpl::OnFirstTimeCredentialsUpload( bool success) { if (!success) { - std::move(on_registered_callback_).Run(/*success=*/false); + OnFirstTimeRegistrationComplete( + metrics::FirstTimeRegistrationResult::kUploadLocalCredentialsFailure); return; } @@ -406,7 +423,8 @@ std::vector<::nearby::internal::SharedCredential> credentials, bool success) { if (!success) { - std::move(on_registered_callback_).Run(/*success=*/false); + OnFirstTimeRegistrationComplete(metrics::FirstTimeRegistrationResult:: + kDownloadRemoteCredentialsFailure); return; } @@ -434,15 +452,14 @@ void NearbyPresenceCredentialManagerImpl::OnFirstTimeRemoteCredentialsSaved( mojom::StatusCode status) { if (status != mojom::StatusCode::kOk) { - // TODO(b/276307539): Add metrics to record failures. - CHECK(on_registered_callback_); - std::move(on_registered_callback_).Run(/*success=*/false); + OnFirstTimeRegistrationComplete( + metrics::FirstTimeRegistrationResult::kSaveRemoteCredentialsFailure); return; } local_device_data_provider_->SetRegistrationComplete(/*complete=*/true); - CHECK(on_registered_callback_); - std::move(on_registered_callback_).Run(/*success=*/true); + OnFirstTimeRegistrationComplete( + metrics::FirstTimeRegistrationResult::kSuccess); } void NearbyPresenceCredentialManagerImpl::StartDailySync() { @@ -710,7 +727,6 @@ void NearbyPresenceCredentialManagerImpl::OnUploadCredentialsTimeout( base::RepeatingCallback<void(bool)> upload_credentials_callback) { - // TODO(b/276307539): Add metrics to record timeout. HandleUploadCredentialsResult( upload_credentials_callback, /*result=*/ash::nearby::NearbyHttpResult::kTimeout); @@ -818,7 +834,6 @@ base::RepeatingCallback< void(std::vector<::nearby::internal::SharedCredential>, bool)> download_credentials_result_callback) { - // TODO(b/276307539): Add metrics to record timeout. HandleDownloadCredentialsResult( download_credentials_result_callback, /*result=*/ash::nearby::NearbyHttpResult::kTimeout, /*credentials=*/{}); @@ -848,7 +863,6 @@ void(std::vector<::nearby::internal::SharedCredential>, bool)> download_credentials_result_callback, ash::nearby::NearbyHttpError error) { - // TODO(b/276307539): Add metrics to record the type of NearbyHttpError. server_response_timer_.Stop(); HandleDownloadCredentialsResult( download_credentials_result_callback,
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h index e0c4ef7..5637082 100644 --- a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl.h
@@ -11,6 +11,7 @@ #include "base/no_destructor.h" #include "base/timer/timer.h" #include "chromeos/ash/components/nearby/common/client/nearby_http_result.h" +#include "chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h" #include "chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom.h" #include "mojo/public/cpp/bindings/shared_remote.h" @@ -142,11 +143,13 @@ private: void StartFirstTimeRegistration(); + void OnFirstTimeRegistrationComplete( + metrics::FirstTimeRegistrationResult result); // Callbacks for server registration UpdateDevice RPC via // |RegisterPresence|. void HandleFirstTimeRegistrationTimeout(); - void HandleFirstTimeRegistrationFailure(); + void HandleFirstTimeRegistrationFailure(ash::nearby::NearbyHttpResult result); void OnRegistrationRpcSuccess( const ash::nearby::proto::UpdateDeviceResponse& response); void OnRegistrationRpcFailure(ash::nearby::NearbyHttpError error); @@ -278,6 +281,12 @@ // success or failure). int download_credentials_attempts_needed_count_ = 0; + // Stores the number of current attempts for registered the local device with + // the Nearby Presence server. Increments on each attempt, and is reset to 0 + // once the registration request is completed (either resulting in final + // success or failure). + int first_time_server_registration_attempts_needed_count_ = 0; + // Initialized during the first time registration flow kicked off in // `RegisterPresence()`. Not expected to be a valid pointer unless used during // the first time registration flow.
diff --git a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc index cf9805ce..2aea932 100644 --- a/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc +++ b/chromeos/ash/components/nearby/presence/credentials/nearby_presence_credential_manager_impl_unittest.cc
@@ -389,6 +389,16 @@ EXPECT_TRUE(credential_manager_); EXPECT_TRUE(credential_manager_->IsLocalDeviceRegistered()); histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeRegistration.Result", + /*bucket: kSuccess=*/0, 1); + histogram_tester_.ExpectTotalCount( + "Nearby.Presence.Credentials.FirstTimeServerRegistration.FailureReason", + 0); + histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeServerRegistration." + "AttemptsNeededCount", + /*bucket: attempt_count=*/1, 1); + histogram_tester_.ExpectBucketCount( "Nearby.Presence.Credentials.Upload.Result", /*bucket: success=*/true, 1); histogram_tester_.ExpectTotalCount( "Nearby.Presence.Credentials.Upload.FailureReason", 0); @@ -423,6 +433,13 @@ create_credential_manager_run_loop.Run(); EXPECT_FALSE(credential_manager_); + histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeRegistration.Result", + /*bucket: kRegistrationWithServerFailure=*/1, 1); + histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeServerRegistration.FailureReason", + /*bucket: NearbyHttpResult::kTimeout*/ + ash::nearby::NearbyHttpResult::kTimeout, 1); } TEST_F(NearbyPresenceCredentialManagerImplTest, ServerRegistrationFailure) { @@ -444,6 +461,13 @@ create_credential_manager_run_loop.Run(); EXPECT_FALSE(credential_manager_); + histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeRegistration.Result", + /*bucket: kRegistrationWithServerFailure=*/1, 1); + histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeServerRegistration.FailureReason", + /*bucket: NearbyHttpResult::kHttpErrorInternalServerError*/ + ash::nearby::NearbyHttpResult::kHttpErrorInternalServerError, 1); } TEST_F(NearbyPresenceCredentialManagerImplTest, CredentialGenerationFailure) { @@ -458,6 +482,9 @@ create_credential_manager_run_loop.Run(); EXPECT_FALSE(credential_manager_); + histogram_tester_.ExpectBucketCount( + "Nearby.Presence.Credentials.FirstTimeRegistration.Result", + /*bucket: kLocalCredentialGenerationFailure=*/2, 1); } TEST_F(NearbyPresenceCredentialManagerImplTest,
diff --git a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc index 838896d0..50165885 100644 --- a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc +++ b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.cc
@@ -42,4 +42,25 @@ success); } +void RecordFirstTimeRegistrationFlowResult(FirstTimeRegistrationResult result) { + base::UmaHistogramEnumeration( + "Nearby.Presence.Credentials.FirstTimeRegistration.Result", result); +} + +void RecordFirstTimeServerRegistrationFailureReason( + ash::nearby::NearbyHttpResult failure_reason) { + base::UmaHistogramEnumeration( + "Nearby.Presence.Credentials.FirstTimeServerRegistration.FailureReason", + failure_reason); +} + +void RecordFirstTimeServerRegistrationTotalAttemptsNeededCount( + int attempt_count) { + base::UmaHistogramExactLinear( + "Nearby.Presence.Credentials.FirstTimeServerRegistration." + "AttemptsNeededCount", + attempt_count, + /*exclusive_max=*/10); +} + } // namespace ash::nearby::presence::metrics
diff --git a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h index 1b903dac..093fb95 100644 --- a/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h +++ b/chromeos/ash/components/nearby/presence/metrics/nearby_presence_metrics.h
@@ -13,11 +13,30 @@ ash::nearby::NearbyHttpResult failure_reason); void RecordSharedCredentialUploadTotalAttemptsNeededCount(int attempt_count); void RecordSharedCredentialUploadResult(bool success); + void RecordSharedCredentialDownloadFailureReason( ash::nearby::NearbyHttpResult failure_reason); void RecordSharedCredentialDownloadTotalAttemptsNeededCount(int attempt_count); void RecordSharedCredentialDownloadResult(bool success); +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. This enum should be kept in sync with +// the FastPairPairFailure enum in src/tools/metrics/histograms/enums.xml. +enum class FirstTimeRegistrationResult { + kSuccess = 0, + kRegistrationWithServerFailure = 1, + kLocalCredentialGenerationFailure = 2, + kUploadLocalCredentialsFailure = 3, + kDownloadRemoteCredentialsFailure = 4, + kSaveRemoteCredentialsFailure = 5, + kMaxValue = kSaveRemoteCredentialsFailure, +}; +void RecordFirstTimeRegistrationFlowResult(FirstTimeRegistrationResult result); +void RecordFirstTimeServerRegistrationFailureReason( + ash::nearby::NearbyHttpResult failure_reason); +void RecordFirstTimeServerRegistrationTotalAttemptsNeededCount( + int attempt_count); + } // namespace ash::nearby::presence::metrics #endif // CHROMEOS_ASH_COMPONENTS_NEARBY_PRESENCE_METRICS_NEARBY_PRESENCE_METRICS_H_
diff --git a/chromeos/ash/components/network/BUILD.gn b/chromeos/ash/components/network/BUILD.gn index 0921790..932bd492 100644 --- a/chromeos/ash/components/network/BUILD.gn +++ b/chromeos/ash/components/network/BUILD.gn
@@ -234,6 +234,8 @@ "fake_network_connection_handler.h", "fake_network_device_handler.cc", "fake_network_device_handler.h", + "fake_network_metadata_store.cc", + "fake_network_metadata_store.h", "fake_stub_cellular_networks_provider.cc", "fake_stub_cellular_networks_provider.h", "mock_managed_cellular_pref_handler.cc",
diff --git a/chromeos/ash/components/network/fake_network_metadata_store.cc b/chromeos/ash/components/network/fake_network_metadata_store.cc new file mode 100644 index 0000000..856343a --- /dev/null +++ b/chromeos/ash/components/network/fake_network_metadata_store.cc
@@ -0,0 +1,36 @@ +// 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 "chromeos/ash/components/network/fake_network_metadata_store.h" + +namespace ash { + +FakeNetworkMetadataStore::FakeNetworkMetadataStore() + : NetworkMetadataStore(/*network_configuration_handler=*/nullptr, + /*network_connection_handler=*/nullptr, + /*network_state_handler=*/nullptr, + /*managed_network_configuration_handler=*/nullptr, + /*profile_pref_service=*/nullptr, + /*device_pref_service=*/nullptr, + /*is_enterprise_managed=*/false) {} + +FakeNetworkMetadataStore::~FakeNetworkMetadataStore() = default; + +UserTextMessageSuppressionState +FakeNetworkMetadataStore::GetUserTextMessageSuppressionState( + const std::string& guid) { + if (auto it = text_message_suppression_state_map_.find(guid); + it != text_message_suppression_state_map_.end()) { + return it->second; + } + return UserTextMessageSuppressionState::kAllow; +} + +void FakeNetworkMetadataStore::SetUserTextMessageSuppressionState( + const std::string& guid, + const UserTextMessageSuppressionState& state) { + text_message_suppression_state_map_[guid] = state; +} + +} // namespace ash
diff --git a/chromeos/ash/components/network/fake_network_metadata_store.h b/chromeos/ash/components/network/fake_network_metadata_store.h new file mode 100644 index 0000000..7af1e0c --- /dev/null +++ b/chromeos/ash/components/network/fake_network_metadata_store.h
@@ -0,0 +1,34 @@ +// 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 CHROMEOS_ASH_COMPONENTS_NETWORK_FAKE_NETWORK_METADATA_STORE_H_ +#define CHROMEOS_ASH_COMPONENTS_NETWORK_FAKE_NETWORK_METADATA_STORE_H_ + +#include <string> + +#include "base/containers/flat_map.h" +#include "chromeos/ash/components/network/network_metadata_store.h" + +namespace ash { + +class FakeNetworkMetadataStore : public NetworkMetadataStore { + public: + FakeNetworkMetadataStore(); + ~FakeNetworkMetadataStore() override; + + UserTextMessageSuppressionState GetUserTextMessageSuppressionState( + const std::string& guid) override; + + void SetUserTextMessageSuppressionState( + const std::string& guid, + const UserTextMessageSuppressionState& state) override; + + private: + base::flat_map<std::string, UserTextMessageSuppressionState> + text_message_suppression_state_map_; +}; + +} // namespace ash + +#endif // CHROMEOS_ASH_COMPONENTS_NETWORK_FAKE_NETWORK_METADATA_STORE_H_
diff --git a/chromeos/ash/components/network/network_handler.cc b/chromeos/ash/components/network/network_handler.cc index ff8d008..433db63 100644 --- a/chromeos/ash/components/network/network_handler.cc +++ b/chromeos/ash/components/network/network_handler.cc
@@ -197,7 +197,8 @@ network_state_handler_.get(), technology_state_controller_.get()); network_sms_handler_->Init(); if (features::IsSuppressTextMessagesEnabled()) { - text_message_provider_->Init(network_sms_handler_.get()); + text_message_provider_->Init(network_sms_handler_.get(), + managed_network_configuration_handler_.get()); } geolocation_handler_->Init(); } @@ -248,6 +249,10 @@ connection_info_metrics_logger_.get())); hidden_network_handler_->SetNetworkMetadataStore( network_metadata_store_.get()); + if (features::IsSuppressTextMessagesEnabled()) { + text_message_provider_->SetNetworkMetadataStore( + network_metadata_store_.get()); + } } void NetworkHandler::ShutdownPrefServices() {
diff --git a/chromeos/ash/components/network/network_metadata_store.h b/chromeos/ash/components/network/network_metadata_store.h index 506e0f50..d43a64e9 100644 --- a/chromeos/ash/components/network/network_metadata_store.h +++ b/chromeos/ash/components/network/network_metadata_store.h
@@ -162,14 +162,14 @@ } // Sets user suppression state to configure text message notifications. - void SetUserTextMessageSuppressionState( + virtual void SetUserTextMessageSuppressionState( const std::string& network_guid, const UserTextMessageSuppressionState& state); // Returns the user set text message suppression state. When no user state has // been configured this will return |TextMessageSuppressionState::kAllow| // which will default to allowing text message notifications. - UserTextMessageSuppressionState GetUserTextMessageSuppressionState( + virtual UserTextMessageSuppressionState GetUserTextMessageSuppressionState( const std::string& network_guid); // Sets whether the deviceReportXDREvents policy is enabled.
diff --git a/chromeos/ash/components/network/network_sms_handler.cc b/chromeos/ash/components/network/network_sms_handler.cc index e2757d6e..a9649a8 100644 --- a/chromeos/ash/components/network/network_sms_handler.cc +++ b/chromeos/ash/components/network/network_sms_handler.cc
@@ -59,6 +59,19 @@ TextMessageData::~TextMessageData() = default; +TextMessageData::TextMessageData(TextMessageData&& other) { + number = std::move(other.number); + text = std::move(other.text); + timestamp = std::move(other.timestamp); +} + +TextMessageData& TextMessageData::operator=(TextMessageData&& other) { + number = std::move(other.number); + text = std::move(other.text); + timestamp = std::move(other.timestamp); + return *this; +} + class NetworkSmsHandler::NetworkSmsDeviceHandler { public: NetworkSmsDeviceHandler() = default;
diff --git a/chromeos/ash/components/network/network_sms_handler.h b/chromeos/ash/components/network/network_sms_handler.h index a35445c..aa86559e 100644 --- a/chromeos/ash/components/network/network_sms_handler.h +++ b/chromeos/ash/components/network/network_sms_handler.h
@@ -26,8 +26,8 @@ TextMessageData(absl::optional<const std::string> number, absl::optional<const std::string> text, absl::optional<const std::string> timestamp); - TextMessageData(TextMessageData&& other) = delete; - TextMessageData& operator=(TextMessageData&& other) = delete; + TextMessageData(TextMessageData&& other); + TextMessageData& operator=(TextMessageData&& other); ~TextMessageData(); absl::optional<std::string> number;
diff --git a/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc index 5bb7e4c..429f74c 100644 --- a/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc +++ b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc
@@ -797,7 +797,8 @@ shill_ip_method == shill::kTypeDHCP) { type = ::onc::ipconfig::kIPv4; } else if (shill_ip_method == shill::kTypeIPv6 || - shill_ip_method == shill::kTypeDHCP6) { + shill_ip_method == shill::kTypeDHCP6 || + shill_ip_method == shill::kTypeSLAAC) { type = ::onc::ipconfig::kIPv6; } else { return; // Ignore unhandled IPConfig types, e.g. bootp, zeroconf, ppp
diff --git a/chromeos/ash/components/network/onc/onc_translator_unittest.cc b/chromeos/ash/components/network/onc/onc_translator_unittest.cc index cec0a7d..f923e23 100644 --- a/chromeos/ash/components/network/onc/onc_translator_unittest.cc +++ b/chromeos/ash/components/network/onc/onc_translator_unittest.cc
@@ -210,7 +210,9 @@ "translation_of_shill_cellular_with_roaming_required_" "and_inactive.onc"), std::make_pair("shill_wifi_eap_empty_certid.json", - "translation_of_shill_wifi_eap_empty_certid.onc"))); + "translation_of_shill_wifi_eap_empty_certid.onc"), + std::make_pair("shill_wifi_with_slaac_ip_config.json", + "translation_of_shill_wifi_with_slaac_ip_config.onc"))); TEST_F(ONCTranslatorShillToOncTest, TranslateCellularApnRevamp) { base::test::ScopedFeatureList scoped_feature_list;
diff --git a/chromeos/ash/components/network/text_message_provider.cc b/chromeos/ash/components/network/text_message_provider.cc index 336fa8e..840d5c1 100644 --- a/chromeos/ash/components/network/text_message_provider.cc +++ b/chromeos/ash/components/network/text_message_provider.cc
@@ -4,8 +4,11 @@ #include "chromeos/ash/components/network/text_message_provider.h" +#include "chromeos/ash/components/network/managed_network_configuration_handler.h" #include "chromeos/ash/components/network/network_handler.h" +#include "chromeos/ash/components/network/network_metadata_store.h" #include "chromeos/ash/components/network/network_sms_handler.h" +#include "chromeos/ash/components/network/text_message_suppression_state.h" #include "components/device_event_log/device_event_log.h" namespace ash { @@ -14,8 +17,15 @@ TextMessageProvider::~TextMessageProvider() = default; -void TextMessageProvider::Init(NetworkSmsHandler* network_sms_handler) { +void TextMessageProvider::Init( + NetworkSmsHandler* network_sms_handler, + ManagedNetworkConfigurationHandler* managed_network_configuration_handler) { + CHECK(network_sms_handler); + CHECK(managed_network_configuration_handler); + managed_network_configuration_handler_ = + managed_network_configuration_handler; network_sms_handler_observer_.Observe(network_sms_handler); + network_policy_observer_.Observe(managed_network_configuration_handler_); } void TextMessageProvider::MessageReceivedFromNetwork( @@ -33,9 +43,18 @@ } } +void TextMessageProvider::PoliciesChanged(const std::string& userhash) { + policy_suppression_state_ = + managed_network_configuration_handler_->GetAllowTextMessages(); +} + bool TextMessageProvider::ShouldAllowTextMessages(const std::string& guid) { - // TODO(b/290350602): Implement ShouldAllowTextMessages with policy. - return true; + if (policy_suppression_state_ != PolicyTextMessageSuppressionState::kUnset) { + return policy_suppression_state_ == + PolicyTextMessageSuppressionState::kAllow; + } + return network_metadata_store_->GetUserTextMessageSuppressionState(guid) == + UserTextMessageSuppressionState::kAllow; } void TextMessageProvider::AddObserver(Observer* observer) { @@ -46,4 +65,10 @@ observers_.RemoveObserver(observer); } +void TextMessageProvider::SetNetworkMetadataStore( + NetworkMetadataStore* network_metadata_store) { + CHECK(network_metadata_store); + network_metadata_store_ = network_metadata_store; +} + } // namespace ash
diff --git a/chromeos/ash/components/network/text_message_provider.h b/chromeos/ash/components/network/text_message_provider.h index 5365e4c..3d9b0a47 100644 --- a/chromeos/ash/components/network/text_message_provider.h +++ b/chromeos/ash/components/network/text_message_provider.h
@@ -9,13 +9,17 @@ #include "base/observer_list_types.h" #include "base/scoped_observation.h" #include "chromeos/ash/components/network/network_handler.h" +#include "chromeos/ash/components/network/network_metadata_store.h" +#include "chromeos/ash/components/network/network_policy_observer.h" #include "chromeos/ash/components/network/network_sms_handler.h" +#include "chromeos/ash/components/network/text_message_suppression_state.h" namespace ash { // Provides non-suppressed text messages to its listeners. class COMPONENT_EXPORT(CHROMEOS_NETWORK) TextMessageProvider - : NetworkSmsHandler::Observer { + : NetworkSmsHandler::Observer, + NetworkPolicyObserver { public: class Observer : public base::CheckedObserver { public: @@ -34,16 +38,37 @@ void MessageReceivedFromNetwork(const std::string& guid, const TextMessageData& message_data) override; + // NetworkPolicyObserver: + void PoliciesChanged(const std::string& userhash) override; + void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - void Init(NetworkSmsHandler* network_sms_handler); + void Init(NetworkSmsHandler* network_sms_handler, + ManagedNetworkConfigurationHandler* + managed_network_configuration_handler); + void SetNetworkMetadataStore(NetworkMetadataStore* network_metadata_store); private: + friend class TextMessageProviderTest; + bool ShouldAllowTextMessages(const std::string& guid); + + PolicyTextMessageSuppressionState policy_suppression_state_ = + PolicyTextMessageSuppressionState::kUnset; + base::ScopedObservation<NetworkSmsHandler, NetworkSmsHandler::Observer> network_sms_handler_observer_{this}; + base::ScopedObservation<ManagedNetworkConfigurationHandler, + NetworkPolicyObserver> + network_policy_observer_{this}; + + raw_ptr<ManagedNetworkConfigurationHandler> + managed_network_configuration_handler_ = nullptr; + + raw_ptr<NetworkMetadataStore> network_metadata_store_ = nullptr; + base::ObserverList<TextMessageProvider::Observer> observers_; };
diff --git a/chromeos/ash/components/network/text_message_provider_unittest.cc b/chromeos/ash/components/network/text_message_provider_unittest.cc index 69699be34..475a69dc 100644 --- a/chromeos/ash/components/network/text_message_provider_unittest.cc +++ b/chromeos/ash/components/network/text_message_provider_unittest.cc
@@ -6,11 +6,18 @@ #include <memory> +#include "ash/constants/ash_features.h" +#include "base/containers/flat_map.h" #include "base/scoped_observation.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "chromeos/ash/components/dbus/shill/shill_clients.h" +#include "chromeos/ash/components/network/fake_network_metadata_store.h" +#include "chromeos/ash/components/network/mock_managed_network_configuration_handler.h" #include "chromeos/ash/components/network/network_handler.h" #include "chromeos/ash/components/network/network_sms_handler.h" +#include "chromeos/ash/components/network/text_message_suppression_state.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -18,9 +25,11 @@ namespace { constexpr char kNumber[] = "000-000-0000"; -constexpr char kText[] = "Fake Sms Message"; +constexpr char kText1[] = "Fake Sms Message 1"; +constexpr char kText2[] = "Fake Sms Message 2"; constexpr char kTimestamp[] = "Thu Aug 3 13:26:04 EDT 2023"; constexpr char kTestGUID1[] = "1"; +constexpr char kTestGUID2[] = "2"; class TestObserver : public TextMessageProvider::Observer { public: @@ -28,16 +37,19 @@ ~TestObserver() override = default; void MessageReceived(const TextMessageData& message_data) override { - last_text_message_.text = message_data.text; - last_text_message_.number = message_data.number; - last_text_message_.timestamp = message_data.timestamp; + text_messages_.emplace_back(message_data.number, message_data.text, + message_data.timestamp); } - const TextMessageData& GetTextMessage() { return last_text_message_; } + const TextMessageData& GetLastTextMessage() { + CHECK(!text_messages_.empty()); + return text_messages_.back(); + } + + size_t MessageCount() { return text_messages_.size(); } private: - TextMessageData last_text_message_{absl::nullopt, absl::nullopt, - absl::nullopt}; + std::vector<TextMessageData> text_messages_; }; } // namespace @@ -52,46 +64,171 @@ network_sms_handler_.reset(new NetworkSmsHandler()); network_sms_handler_->Init(); provider_ = std::make_unique<TextMessageProvider>(); - provider_->Init(network_sms_handler_.get()); + provider_->Init(network_sms_handler_.get(), + &mock_managed_network_configuration_handler_); + provider_->SetNetworkMetadataStore(&fake_network_metadata_store_); + observation.Observe(provider_.get()); } void TearDown() override { // These need to be destroyed in reverse order as we need to shutdown the // fakes from shill_client. + observation.Reset(); provider_.reset(); network_sms_handler_.reset(); shill_clients::Shutdown(); } - TestObserver* test_observer() { return &test_observer_; } - - void ObserveProvider( - base::ScopedObservation<TextMessageProvider, - TextMessageProvider::Observer>& observation) { - observation.Observe(provider_.get()); + void SimulateMessageReceived(const std::string& guid, + const TextMessageData& data) { + provider_->MessageReceivedFromNetwork(guid, data); } - void SimulateMessageReceived(const TextMessageData& data) { - provider_->MessageReceivedFromNetwork(kTestGUID1, data); + void SimulatePolicyChanged() { provider_->PoliciesChanged(/*userhash=*/""); } + + void AssertTestObserverValue( + size_t expected_count, + absl::optional<TextMessageData> expected_message) { + ASSERT_EQ(expected_count, test_observer_.MessageCount()); + + if (!expected_message.has_value()) { + return; + } + EXPECT_EQ(expected_message->number.value(), + test_observer_.GetLastTextMessage().number.value()); + EXPECT_EQ(expected_message->text.value(), + test_observer_.GetLastTextMessage().text.value()); + EXPECT_EQ(expected_message->timestamp.value(), + test_observer_.GetLastTextMessage().timestamp.value()); + } + + MockManagedNetworkConfigurationHandler* + mock_managed_network_configuration_handler() { + return &mock_managed_network_configuration_handler_; + } + + FakeNetworkMetadataStore* fake_network_metadata_store() { + return &fake_network_metadata_store_; } private: TestObserver test_observer_; + testing::NiceMock<MockManagedNetworkConfigurationHandler> + mock_managed_network_configuration_handler_; + + FakeNetworkMetadataStore fake_network_metadata_store_; std::unique_ptr<NetworkSmsHandler> network_sms_handler_; std::unique_ptr<TextMessageProvider> provider_; base::test::SingleThreadTaskEnvironment task_environment_; + + base::ScopedObservation<TextMessageProvider, TextMessageProvider::Observer> + observation{&test_observer_}; + base::test::ScopedFeatureList features_{features::kSuppressTextMessages}; }; -TEST_F(TextMessageProviderTest, ObserverTest) { - base::ScopedObservation<TextMessageProvider, TextMessageProvider::Observer> - observation{test_observer()}; - ObserveProvider(observation); - const TextMessageData message_data{kNumber, kText, kTimestamp}; - SimulateMessageReceived(message_data); +TEST_F(TextMessageProviderTest, MessageReceivedPolicyAllowUserSuppressTest) { + EXPECT_CALL(*mock_managed_network_configuration_handler(), + GetAllowTextMessages) + .WillOnce(::testing::Return(PolicyTextMessageSuppressionState::kAllow)); - EXPECT_EQ(test_observer()->GetTextMessage().number.value(), kNumber); - EXPECT_EQ(test_observer()->GetTextMessage().text.value(), kText); - EXPECT_EQ(test_observer()->GetTextMessage().timestamp.value(), kTimestamp); + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID1, UserTextMessageSuppressionState::kSuppress); + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID2, UserTextMessageSuppressionState::kSuppress); + + TextMessageData message_data{kNumber, kText1, kTimestamp}; + TextMessageData message_data_2{kNumber, kText2, kTimestamp}; + + SimulatePolicyChanged(); + SimulateMessageReceived(kTestGUID1, message_data); + AssertTestObserverValue( + /*expected_count=*/1, std::move(message_data)); + SimulateMessageReceived(kTestGUID2, message_data_2); + AssertTestObserverValue( + /*expected_count=*/2, std::move(message_data_2)); +} + +TEST_F(TextMessageProviderTest, MessageReceivedPolicySuppressUserAllowTest) { + EXPECT_CALL(*mock_managed_network_configuration_handler(), + GetAllowTextMessages) + .WillOnce( + ::testing::Return(PolicyTextMessageSuppressionState::kSuppress)); + + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID1, UserTextMessageSuppressionState::kAllow); + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID2, UserTextMessageSuppressionState::kAllow); + + SimulatePolicyChanged(); + SimulateMessageReceived(kTestGUID1, {kNumber, kText1, kTimestamp}); + AssertTestObserverValue(/*expected_count=*/0, absl::nullopt); + SimulateMessageReceived(kTestGUID2, {kNumber, kText2, kTimestamp}); + AssertTestObserverValue(/*expected_count=*/0, absl::nullopt); +} + +TEST_F(TextMessageProviderTest, MessageReceivedPolicyAllowUserAllowTest) { + EXPECT_CALL(*mock_managed_network_configuration_handler(), + GetAllowTextMessages) + .WillOnce(::testing::Return(PolicyTextMessageSuppressionState::kAllow)); + + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID1, UserTextMessageSuppressionState::kAllow); + + TextMessageData message_data{kNumber, kText1, kTimestamp}; + + SimulatePolicyChanged(); + SimulateMessageReceived(kTestGUID1, message_data); + AssertTestObserverValue( + /*expected_count=*/1, std::move(message_data)); +} + +TEST_F(TextMessageProviderTest, MessageReceivedPolicySuppressUserSuppressTest) { + EXPECT_CALL(*mock_managed_network_configuration_handler(), + GetAllowTextMessages) + .WillOnce( + ::testing::Return(PolicyTextMessageSuppressionState::kSuppress)); + + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID1, UserTextMessageSuppressionState::kSuppress); + + SimulatePolicyChanged(); + SimulateMessageReceived(kTestGUID1, {kNumber, kText1, kTimestamp}); + AssertTestObserverValue( + /*expected_count=*/0, absl::nullopt); +} + +TEST_F(TextMessageProviderTest, + MessageReceivedPolicyUnsetOneNetworkAllowOneNetworkSuppressTest) { + EXPECT_CALL(*mock_managed_network_configuration_handler(), + GetAllowTextMessages) + .WillOnce(::testing::Return(PolicyTextMessageSuppressionState::kUnset)); + SimulatePolicyChanged(); + + // User suppression state is Allow for |kTestGUID1| and Suppress for + // |kTestGUID2|. + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID1, UserTextMessageSuppressionState::kAllow); + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID2, UserTextMessageSuppressionState::kSuppress); + + TextMessageData message_data{kNumber, kText1, kTimestamp}; + SimulateMessageReceived(kTestGUID2, message_data); + AssertTestObserverValue(/*expected_count=*/0, absl::nullopt); + SimulateMessageReceived(kTestGUID1, message_data); + AssertTestObserverValue(/*expected_count=*/1, std::move(message_data)); + + // User suppression state is Suppress for |kTestGUID1| and Allow for + // |kTestGUID2|. + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID1, UserTextMessageSuppressionState::kSuppress); + fake_network_metadata_store()->SetUserTextMessageSuppressionState( + kTestGUID2, UserTextMessageSuppressionState::kAllow); + + TextMessageData message_data_2{kNumber, kText2, kTimestamp}; + SimulateMessageReceived(kTestGUID1, message_data_2); + AssertTestObserverValue(/*expected_count=*/1, absl::nullopt); + SimulateMessageReceived(kTestGUID2, message_data_2); + AssertTestObserverValue(/*expected_count=*/2, std::move(message_data_2)); } } // namespace ash
diff --git a/chromeos/ash/components/tether/wifi_hotspot_connector.h b/chromeos/ash/components/tether/wifi_hotspot_connector.h index 62c61cc7..81175d9c 100644 --- a/chromeos/ash/components/tether/wifi_hotspot_connector.h +++ b/chromeos/ash/components/tether/wifi_hotspot_connector.h
@@ -87,7 +87,7 @@ NetworkStateHandlerScopedObservation network_state_handler_observer_{this}; - raw_ptr<NetworkConnect, ExperimentalAsh> network_connect_; + raw_ptr<NetworkConnect, DanglingUntriaged | ExperimentalAsh> network_connect_; std::unique_ptr<base::OneShotTimer> timer_; raw_ptr<base::Clock, ExperimentalAsh> clock_;
diff --git a/chromeos/ash/services/network_config/cros_network_config.cc b/chromeos/ash/services/network_config/cros_network_config.cc index d98b6399..b1c7bc2 100644 --- a/chromeos/ash/services/network_config/cros_network_config.cc +++ b/chromeos/ash/services/network_config/cros_network_config.cc
@@ -42,6 +42,7 @@ #include "chromeos/ash/components/network/prohibited_technologies_handler.h" #include "chromeos/ash/components/network/proxy/ui_proxy_config_service.h" #include "chromeos/ash/components/network/technology_state_controller.h" +#include "chromeos/ash/components/network/text_message_suppression_state.h" #include "chromeos/ash/components/sync_wifi/network_eligibility_checker.h" #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-shared.h" @@ -1636,11 +1637,23 @@ ->GetUserTextMessageSuppressionState(network_state->guid()); cellular->allow_text_messages = mojom::ManagedBoolean::New(); cellular->allow_text_messages->active_value = - state != UserTextMessageSuppressionState::kSuppress; - - // TODO(b/293432140) Map the policy value from - // |ManagedNetworkConfigurationHandler| to the policy_value of the - // |allow_text_messages| property. + state == UserTextMessageSuppressionState::kAllow; + PolicyTextMessageSuppressionState policy_state = + NetworkHandler::Get() + ->managed_network_configuration_handler() + ->GetAllowTextMessages(); + if (policy_state != PolicyTextMessageSuppressionState::kUnset) { + cellular->allow_text_messages->policy_value = + policy_state == PolicyTextMessageSuppressionState::kAllow; + // |active_value| should match policy value when policy is enforced. + cellular->allow_text_messages->active_value = + cellular->allow_text_messages->policy_value; + // We manually set the policy source to device enforced as that aligns + // with the implemented behavior. This field is read in WebUI to + // determine whether the policy value should be used or not. + cellular->allow_text_messages->policy_source = ::chromeos:: + network_config::mojom::PolicySource::kDevicePolicyEnforced; + } } result->type_properties = mojom::NetworkTypeManagedProperties::NewCellular(std::move(cellular));
diff --git a/chromeos/ash/services/network_config/cros_network_config.h b/chromeos/ash/services/network_config/cros_network_config.h index 8430076..a0af7e4 100644 --- a/chromeos/ash/services/network_config/cros_network_config.h +++ b/chromeos/ash/services/network_config/cros_network_config.h
@@ -215,20 +215,21 @@ NetworkStateHandlerScopedObservation network_state_handler_observer_{this}; - raw_ptr<NetworkDeviceHandler, ExperimentalAsh> - network_device_handler_; // Unowned - raw_ptr<CellularInhibitor, ExperimentalAsh> cellular_inhibitor_; // Unowned - raw_ptr<CellularESimProfileHandler, ExperimentalAsh> + raw_ptr<NetworkDeviceHandler, LeakedDanglingUntriaged | ExperimentalAsh> + network_device_handler_; // Unowned + raw_ptr<CellularInhibitor, LeakedDanglingUntriaged | ExperimentalAsh> + cellular_inhibitor_; // Unowned + raw_ptr<CellularESimProfileHandler, LeakedDanglingUntriaged | ExperimentalAsh> cellular_esim_profile_handler_; // Unowned raw_ptr<ManagedNetworkConfigurationHandler, ExperimentalAsh> network_configuration_handler_; // Unowned - raw_ptr<NetworkConnectionHandler, ExperimentalAsh> + raw_ptr<NetworkConnectionHandler, LeakedDanglingUntriaged | ExperimentalAsh> network_connection_handler_; // Unowned - raw_ptr<NetworkCertificateHandler, ExperimentalAsh> + raw_ptr<NetworkCertificateHandler, LeakedDanglingUntriaged | ExperimentalAsh> network_certificate_handler_; // Unowned - raw_ptr<NetworkProfileHandler, ExperimentalAsh> + raw_ptr<NetworkProfileHandler, LeakedDanglingUntriaged | ExperimentalAsh> network_profile_handler_; // Unowned - raw_ptr<TechnologyStateController, ExperimentalAsh> + raw_ptr<TechnologyStateController, LeakedDanglingUntriaged | ExperimentalAsh> technology_state_controller_; // Unowned mojo::RemoteSet<chromeos::network_config::mojom::CrosNetworkConfigObserver>
diff --git a/chromeos/ash/services/network_config/cros_network_config_unittest.cc b/chromeos/ash/services/network_config/cros_network_config_unittest.cc index b42dbc6..f6a506c 100644 --- a/chromeos/ash/services/network_config/cros_network_config_unittest.cc +++ b/chromeos/ash/services/network_config/cros_network_config_unittest.cc
@@ -47,6 +47,7 @@ #include "chromeos/components/onc/onc_utils.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-shared.h" +#include "chromeos/services/network_config/public/mojom/network_types.mojom-shared.h" #include "components/captive_portal/core/captive_portal_detector.h" #include "components/onc/onc_constants.h" #include "components/onc/onc_pref_names.h" @@ -1060,23 +1061,40 @@ ApnTypes::kDefaultAndAttach, count.num_disable_type_default_and_attach); } - void AssertCellularAllowTextMessages(const std::string& guid, - absl::optional<bool> expected_value) { + void AssertCellularAllowTextMessages( + const std::string& guid, + absl::optional<bool> expected_active_value, + absl::optional<bool> expected_policy_value, + ::chromeos::network_config::mojom::PolicySource policy_source) { mojom::ManagedPropertiesPtr properties = GetManagedProperties(guid); ASSERT_TRUE(properties); ASSERT_EQ(guid, properties->guid); ASSERT_TRUE(properties->type_properties->is_cellular()); - if (expected_value.has_value()) { - ASSERT_TRUE( - properties->type_properties->get_cellular()->allow_text_messages); - // TODO(b/293432140) Add checks for policy value along with policy source - // when they are in effect. - EXPECT_EQ(expected_value, properties->type_properties->get_cellular() - ->allow_text_messages->active_value); - } else { + // If there isn't an expected policy or actual value, that means the + // property is undefined. + if (!expected_active_value.has_value() && + !expected_policy_value.has_value()) { EXPECT_FALSE( properties->type_properties->get_cellular()->allow_text_messages); + return; + } + + ASSERT_TRUE( + properties->type_properties->get_cellular()->allow_text_messages); + EXPECT_EQ(policy_source, properties->type_properties->get_cellular() + ->allow_text_messages->policy_source); + + if (expected_policy_value.has_value()) { + EXPECT_EQ(*expected_policy_value, + properties->type_properties->get_cellular() + ->allow_text_messages->policy_value); + } + + if (expected_active_value.has_value()) { + EXPECT_EQ(*expected_active_value, + properties->type_properties->get_cellular() + ->allow_text_messages->active_value); } } @@ -3067,7 +3085,9 @@ scoped_feature_list.InitAndEnableFeature(features::kSuppressTextMessages); // When never set, allow_text_messages will be true. - AssertCellularAllowTextMessages(kCellularGuid, /*expected_value=*/true); + AssertCellularAllowTextMessages(kCellularGuid, /*expected_active_value=*/true, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); // When text message state is set to false, the value will be updated to // false. @@ -3080,7 +3100,9 @@ config->type_config = mojom::NetworkTypeConfigProperties::NewCellular( std::move(cellular_config)); ASSERT_TRUE(SetProperties(kCellularGuid, std::move(config))); - AssertCellularAllowTextMessages(kCellularGuid, /*expected_value=*/false); + AssertCellularAllowTextMessages( + kCellularGuid, /*expected_active_value=*/false, + /*expected_policy_value=*/absl::nullopt, mojom::PolicySource::kNone); // When text message state is undefined, this will not update the last saved // value of false. @@ -3088,7 +3110,9 @@ config->type_config = mojom::NetworkTypeConfigProperties::NewCellular( mojom::CellularConfigProperties::New()); ASSERT_TRUE(SetProperties(kCellularGuid, std::move(config))); - AssertCellularAllowTextMessages(kCellularGuid, /*expected_value=*/false); + AssertCellularAllowTextMessages( + kCellularGuid, /*expected_active_value=*/false, + /*expected_policy_value=*/absl::nullopt, mojom::PolicySource::kNone); // When text message state is set to true, the value will be updated to true. config = mojom::ConfigProperties::New(); @@ -3101,7 +3125,9 @@ std::move(cellular_config)); ASSERT_TRUE(SetProperties(kCellularGuid, std::move(config))); - AssertCellularAllowTextMessages(kCellularGuid, /*expected_value=*/true); + AssertCellularAllowTextMessages(kCellularGuid, /*expected_active_value=*/true, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); // When text message state is undefined, this will not update the last saved // value of true. @@ -3109,7 +3135,71 @@ config->type_config = mojom::NetworkTypeConfigProperties::NewCellular( mojom::CellularConfigProperties::New()); ASSERT_TRUE(SetProperties(kCellularGuid, std::move(config))); - AssertCellularAllowTextMessages(kCellularGuid, /*expected_value=*/true); + AssertCellularAllowTextMessages(kCellularGuid, /*expected_active_value=*/true, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); +} + +TEST_F(CrosNetworkConfigTest, + AllowTextMessagesPolicyValueWithSuppressTextMessagesFlagEnabled) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kSuppressTextMessages); + + base::Value::Dict global_config; + + // When the policy is explicitly Suppress, the managed boolean policy value + // should return false and the policy source should be device enforced. + global_config.Set(::onc::global_network_config::kAllowTextMessages, + ::onc::cellular::kTextMessagesSuppress); + + managed_network_configuration_handler()->SetPolicy( + ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), + /*network_configs_onc=*/base::Value::List(), global_config); + base::RunLoop().RunUntilIdle(); + + AssertCellularAllowTextMessages(kCellularGuid, + /*expected_active_value=*/false, + /*expected_policy_value=*/false, + mojom::PolicySource::kDevicePolicyEnforced); + + // When the policy is explicitly Allow, the managed boolean policy value + // should return true and the policy source should be device enforced. + global_config.Set(::onc::global_network_config::kAllowTextMessages, + ::onc::cellular::kTextMessagesAllow); + managed_network_configuration_handler()->SetPolicy( + ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), + /*network_configs_onc=*/base::Value::List(), global_config); + base::RunLoop().RunUntilIdle(); + + AssertCellularAllowTextMessages(kCellularGuid, + /*expected_active_value=*/true, + /*expected_policy_value=*/true, + mojom::PolicySource::kDevicePolicyEnforced); + + // When the policy is explicitly Unset, we default to the user set value. + global_config.Set(::onc::global_network_config::kAllowTextMessages, + ::onc::cellular::kTextMessagesUnset); + managed_network_configuration_handler()->SetPolicy( + ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), + /*network_configs_onc=*/base::Value::List(), global_config); + base::RunLoop().RunUntilIdle(); + + AssertCellularAllowTextMessages(kCellularGuid, + /*expected_active_value=*/true, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); + + // When global network configuration is not set, we treat it as unset. + managed_network_configuration_handler()->SetPolicy( + ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), + /*network_configs_onc=*/base::Value::List(), + /*global_network_config=*/base::Value::Dict()); + base::RunLoop().RunUntilIdle(); + + AssertCellularAllowTextMessages(kCellularGuid, + /*expected_active_value=*/true, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); } TEST_F(CrosNetworkConfigTest, @@ -3119,7 +3209,9 @@ // When never set, this will return undefined. AssertCellularAllowTextMessages(kCellularGuid, - /*expected_value=*/absl::nullopt); + /*expected_active_value=*/absl::nullopt, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); // When set to any value, will still return undefined. auto config = mojom::ConfigProperties::New(); @@ -3129,7 +3221,9 @@ new_text_message_state->allow_text_messages = true; cellular_config->text_message_allow_state = std::move(new_text_message_state); AssertCellularAllowTextMessages(kCellularGuid, - /*expected_value=*/absl::nullopt); + /*expected_active_value=*/absl::nullopt, + /*expected_policy_value=*/absl::nullopt, + mojom::PolicySource::kNone); } TEST_F(CrosNetworkConfigTest, ConfigureNetwork) {
diff --git a/chromeos/ash/services/secure_channel/connection_attempt_base_unittest.cc b/chromeos/ash/services/secure_channel/connection_attempt_base_unittest.cc index 20a950e..dc0413d 100644 --- a/chromeos/ash/services/secure_channel/connection_attempt_base_unittest.cc +++ b/chromeos/ash/services/secure_channel/connection_attempt_base_unittest.cc
@@ -77,7 +77,7 @@ } raw_ptr<FakeConnectToDeviceOperation<BleInitiatorFailureType>, - ExperimentalAsh> + DanglingUntriaged | ExperimentalAsh> fake_operation_ = nullptr; };
diff --git a/chromeos/components/test/data/onc/shill_wifi_with_slaac_ip_config.json b/chromeos/components/test/data/onc/shill_wifi_with_slaac_ip_config.json new file mode 100644 index 0000000..bdce91a --- /dev/null +++ b/chromeos/components/test/data/onc/shill_wifi_with_slaac_ip_config.json
@@ -0,0 +1,25 @@ +{ + "GUID":"guid", + "IPConfigs":[ + { + "Address":"123.123.123.123", + "Gateway":"1.1.1.1", + "Method":"ipv4", + "NameServers":[ + "1.1.1.2", + "1.1.1.3" + ], + "Prefixlen":24, + "WebProxyAutoDiscoveryUrl":"proxy.url" + }, + { + "Address":"2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "Gateway":"2001:db8:85a3::7a2e:370:7331", + "Method":"slaac", + "NameServers":[], + "Prefixlen":64 + } + ], + "Type":"wifi", + "Name":"test_wifi" +} \ No newline at end of file
diff --git a/chromeos/components/test/data/onc/translation_of_shill_wifi_with_slaac_ip_config.onc b/chromeos/components/test/data/onc/translation_of_shill_wifi_with_slaac_ip_config.onc new file mode 100644 index 0000000..0ee2af31 --- /dev/null +++ b/chromeos/components/test/data/onc/translation_of_shill_wifi_with_slaac_ip_config.onc
@@ -0,0 +1,27 @@ +{ + "GUID":"guid", + "IPAddressConfigType": "DHCP", + "IPConfigs":[ + { + "Gateway":"1.1.1.1", + "IPAddress":"123.123.123.123", + "NameServers":[ + "1.1.1.2", + "1.1.1.3" + ], + "RoutingPrefix":24, + "Type":"IPv4", + "WebProxyAutoDiscoveryUrl":"proxy.url" + }, + { + "Gateway":"2001:db8:85a3::7a2e:370:7331", + "IPAddress":"2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "NameServers":[], + "RoutingPrefix":64, + "Type":"IPv6" + } + ], + "Name": "test_wifi", + "NameServersConfigType": "DHCP", + "Type": "WiFi" +} \ No newline at end of file
diff --git a/components/BUILD.gn b/components/BUILD.gn index 5be5fe9..95333e15 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -418,6 +418,10 @@ ] } + if (is_linux || is_win || is_mac || is_android) { + deps += [ "//components/enterprise/idle:unit_tests" ] + } + if (is_ios) { deps += [ ":components_tests_pak_bundle_data",
diff --git a/components/autofill/core/browser/heuristic_classification_unittests.cc b/components/autofill/core/browser/heuristic_classification_unittests.cc index 2159e0ff..81bc68a 100644 --- a/components/autofill/core/browser/heuristic_classification_unittests.cc +++ b/components/autofill/core/browser/heuristic_classification_unittests.cc
@@ -288,9 +288,10 @@ // Returns all "*.json" files in `GetInputDir()`. std::vector<base::FilePath> GetTestFiles() { - base::FileEnumerator input_files(GetInputDir(), false, - base::FileEnumerator::FILES, - FILE_PATH_LITERAL("*.json")); + base::FileEnumerator input_files( + GetInputDir(), /*recursive=*/true, base::FileEnumerator::FILES, + FILE_PATH_LITERAL("*.json"), + base::FileEnumerator::FolderSearchPolicy::ALL); std::vector<base::FilePath> files; input_files.ForEach( [&files](const base::FilePath& item) { files.push_back(item); }); @@ -429,10 +430,9 @@ TEST_P(HeuristicClassificationTests, EndToEnd) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableSupportForBetweenStreets, - features::kAutofillEnableSupportForAdminLevel2, - features::kAutofillEnableSupportForAddressOverflow, - features::kAutofillEnableSupportForLandmark}, + /*enabled_features=*/ + {// This is always enabled to classify autocomplete=invalid fields. + features::kAutofillPredictionsForAutocompleteUnrecognized}, /*disabled_features=*/{}); base::FilePath input_file = GetParam();
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index f0ec75b9..8a4e09f 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -142,6 +142,12 @@ "AutofillEnableRemadeDownstreamMetrics", base::FEATURE_ENABLED_BY_DEFAULT); +// When enabled, Autofill will attempt to offer upload save for IBANs +// (International Bank Account Numbers) and autofill server-based IBANs. +BASE_FEATURE(kAutofillEnableServerIban, + "AutofillEnableServerIban", + base::FEATURE_DISABLED_BY_DEFAULT); + // When enabled, if the user interacts with the manual fallback bottom sheet // on Android, it'll remain sticky until the user dismisses it. BASE_FEATURE(kAutofillEnableStickyManualFallbackForCards,
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index a7492e2..d69e661a 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -36,6 +36,7 @@ BASE_DECLARE_FEATURE(kAutofillEnablePaymentsMandatoryReauth); BASE_DECLARE_FEATURE(kAutofillEnableRemadeDownstreamMetrics); +BASE_DECLARE_FEATURE(kAutofillEnableServerIban); BASE_DECLARE_FEATURE(kAutofillEnableStickyManualFallbackForCards); BASE_DECLARE_FEATURE(kAutofillEnableUpdateVirtualCardEnrollment); BASE_DECLARE_FEATURE(kAutofillEnableVirtualCard);
diff --git a/components/autofill/core/common/autofill_prefs.cc b/components/autofill/core/common/autofill_prefs.cc index 7af9152..5ed7852 100644 --- a/components/autofill/core/common/autofill_prefs.cc +++ b/components/autofill/core/common/autofill_prefs.cc
@@ -108,12 +108,16 @@ const char kAutocompleteLastVersionRetentionPolicy[] = "autocomplete.retention_policy_last_version"; -#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_IOS) // Boolean that is set when payment methods mandatory re-auth is enabled by the // user. const char kAutofillPaymentMethodsMandatoryReauth[] = "autofill.payment_methods_mandatory_reauth"; +#endif // #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) + // || BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) // Integer that is incremented when the mandatory re-auth promo is shown. If // this is less than `kMaxValueForMandatoryReauthPromoShownCounter`, that // implies that the user has not yet decided whether or not to turn on the @@ -178,7 +182,10 @@ false); registry->RegisterIntegerPref( prefs::kAutofillPaymentMethodsMandatoryReauthPromoShownCounter, 0); -#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#elif BUILDFLAG(IS_IOS) + registry->RegisterBooleanPref(prefs::kAutofillPaymentMethodsMandatoryReauth, + true); +#endif // Deprecated prefs registered for migration. registry->RegisterBooleanPref( @@ -258,22 +265,23 @@ } bool IsPaymentMethodsMandatoryReauthEnabled(const PrefService* prefs) { -#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) - if (!base::FeatureList::IsEnabled( - features::kAutofillEnablePaymentsMandatoryReauth)) { - return false; - } - - return prefs->GetBoolean(kAutofillPaymentMethodsMandatoryReauth); +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_IOS) + return base::FeatureList::IsEnabled( + features::kAutofillEnablePaymentsMandatoryReauth) && + prefs->GetBoolean(kAutofillPaymentMethodsMandatoryReauth); #else return false; -#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_IOS) } void SetPaymentMethodsMandatoryReauthEnabled(PrefService* prefs, bool enabled) { -#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_IOS) prefs->SetBoolean(kAutofillPaymentMethodsMandatoryReauth, enabled); -#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_IOS) } bool IsPaymentMethodsMandatoryReauthSetExplicitly(const PrefService* prefs) {
diff --git a/components/autofill/core/common/autofill_prefs.h b/components/autofill/core/common/autofill_prefs.h index 93b4369f..ddbdd4b 100644 --- a/components/autofill/core/common/autofill_prefs.h +++ b/components/autofill/core/common/autofill_prefs.h
@@ -43,8 +43,12 @@ extern const char kAutofillUploadEvents[]; extern const char kAutofillUploadEventsLastResetTimestamp[]; extern const char kAutocompleteLastVersionRetentionPolicy[]; -#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_IOS) extern const char kAutofillPaymentMethodsMandatoryReauth[]; +#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) extern const char kAutofillPaymentMethodsMandatoryReauthPromoShownCounter[]; #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_ANDROID)
diff --git a/components/autofill/ios/browser/autofill_java_script_feature.mm b/components/autofill/ios/browser/autofill_java_script_feature.mm index d65e690..2ac2cdc8 100644 --- a/components/autofill/ios/browser/autofill_java_script_feature.mm +++ b/components/autofill/ios/browser/autofill_java_script_feature.mm
@@ -35,7 +35,9 @@ AutofillJavaScriptFeature::AutofillJavaScriptFeature() : web::JavaScriptFeature( - web::ContentWorld::kIsolatedWorld, + // TODO(crbug.com/1175793): Move autofill code to kIsolatedWorld + // once all scripts are converted to JavaScriptFeatures. + web::ContentWorld::kPageContentWorld, {FeatureScript::CreateWithFilename( kScriptName, FeatureScript::InjectionTime::kDocumentStart,
diff --git a/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm b/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm index d2ef5b9..671d3add2 100644 --- a/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm +++ b/components/autofill/ios/browser/suggestion_controller_java_script_feature.mm
@@ -63,7 +63,9 @@ SuggestionControllerJavaScriptFeature::SuggestionControllerJavaScriptFeature() : web::JavaScriptFeature( - web::ContentWorld::kIsolatedWorld, + // TODO(crbug.com/1175793): Move autofill code to kIsolatedWorld + // once all scripts are converted to JavaScriptFeatures. + web::ContentWorld::kPageContentWorld, {FeatureScript::CreateWithFilename( kScriptName, FeatureScript::InjectionTime::kDocumentStart,
diff --git a/components/autofill/ios/form_util/form_handlers_java_script_feature.mm b/components/autofill/ios/form_util/form_handlers_java_script_feature.mm index 9011e8a..cefe0665 100644 --- a/components/autofill/ios/form_util/form_handlers_java_script_feature.mm +++ b/components/autofill/ios/form_util/form_handlers_java_script_feature.mm
@@ -26,7 +26,9 @@ FormHandlersJavaScriptFeature::FormHandlersJavaScriptFeature() : web::JavaScriptFeature( - web::ContentWorld::kIsolatedWorld, + // TODO(crbug.com/1175793): Move autofill code to kIsolatedWorld + // once all scripts are converted to JavaScriptFeatures. + web::ContentWorld::kPageContentWorld, {FeatureScript::CreateWithFilename( kScriptName, FeatureScript::InjectionTime::kDocumentStart,
diff --git a/components/autofill/ios/form_util/form_util_java_script_feature.mm b/components/autofill/ios/form_util/form_util_java_script_feature.mm index c1b05ef..c4c80a4 100644 --- a/components/autofill/ios/form_util/form_util_java_script_feature.mm +++ b/components/autofill/ios/form_util/form_util_java_script_feature.mm
@@ -23,7 +23,9 @@ FormUtilJavaScriptFeature::FormUtilJavaScriptFeature() : web::JavaScriptFeature( - web::ContentWorld::kIsolatedWorld, + // TODO(crbug.com/1175793): Move autofill code to kIsolatedWorld + // once all scripts are converted to JavaScriptFeatures. + web::ContentWorld::kPageContentWorld, {FeatureScript::CreateWithFilename( kFillScriptName, FeatureScript::InjectionTime::kDocumentStart,
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TintedDrawable.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TintedDrawable.java index 4bfe467..575d5155 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TintedDrawable.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TintedDrawable.java
@@ -8,6 +8,7 @@ import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -15,14 +16,19 @@ import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; +import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; +import org.chromium.base.Log; + /** * Implementation of BitmapDrawable that allows to tint the color of the drawable for all * bitmap drawable states. */ public class TintedDrawable extends BitmapDrawable { + private static final String TAG = "TD"; + /** * The set of colors that just be used for tinting this bitmap drawable. */ @@ -45,6 +51,16 @@ return true; } + @Override + public void draw(Canvas canvas) { + // Add extra method to stack and logging for https://crbug.com/1457791. + final @Nullable Bitmap bitmap = getBitmap(); + if (bitmap != null && bitmap.isRecycled()) { + Log.e(TAG, "Trying to draw with recycled BitmapDrawable."); + } + super.draw(canvas); + } + /** * Sets the tint color for the given Drawable for all button states. * @param tint The set of colors to use to color the ImageButton.
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java index 0e2384c..3e63aa8 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java
@@ -4,7 +4,9 @@ package org.chromium.components.browser_ui.widget.gesture; +import androidx.activity.BackEventCompat; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -99,4 +101,22 @@ default ObservableSupplier<Boolean> getHandleBackPressChangedSupplier() { return new ObservableSupplierImpl<>(); } + + /** + * API 34+ only. Triggered when a back press press is cancelled. In this case, + * {@link #handleBackPress()} must not be triggered any more. + */ + default void handleOnBackCancelled() {} + + /** + * API 34+ only. Triggered after a back press is started + * ({@link #handleOnBackStarted(BackEventCompat)}) and before a back press is released + * (either {@link #handleBackPress()} or {@link #handleOnBackCancelled()}) + */ + default void handleOnBackProgressed(@NonNull BackEventCompat backEvent) {} + + /** + * API 34+ only. Triggered when a back press event is initialized. + */ + default void handleOnBackStarted(@NonNull BackEventCompat backEvent) {} }
diff --git a/components/device_signals/core/browser/BUILD.gn b/components/device_signals/core/browser/BUILD.gn index a64146c..59ae1d1 100644 --- a/components/device_signals/core/browser/BUILD.gn +++ b/components/device_signals/core/browser/BUILD.gn
@@ -44,6 +44,7 @@ deps = [ "//components/device_signals/core/common", + "//components/device_signals/core/common:features", "//components/policy/core/common", "//components/prefs", "//components/signin/public/identity_manager", @@ -107,6 +108,7 @@ ":test_support", "//base/test:test_support", "//components/device_signals/core/common", + "//components/device_signals/core/common:features", "//components/policy/core/common", "//components/policy/core/common:test_support", "//components/prefs",
diff --git a/components/device_signals/core/browser/user_permission_service_impl.cc b/components/device_signals/core/browser/user_permission_service_impl.cc index 0388045..41b4aa5 100644 --- a/components/device_signals/core/browser/user_permission_service_impl.cc +++ b/components/device_signals/core/browser/user_permission_service_impl.cc
@@ -7,16 +7,27 @@ #include <set> #include "base/check.h" +#include "base/feature_list.h" #include "base/functional/bind.h" #include "components/device_signals/core/browser/pref_names.h" #include "components/device_signals/core/browser/user_context.h" #include "components/device_signals/core/browser/user_delegate.h" +#include "components/device_signals/core/common/signals_features.h" #include "components/policy/core/common/management/management_service.h" #include "components/policy/core/common/policy_types.h" #include "components/prefs/pref_service.h" namespace device_signals { +namespace { + +bool IsNewEvSignalsUnaffiliatedEnabled() { + return base::FeatureList::IsEnabled( + enterprise_signals::features::kNewEvSignalsUnaffiliatedEnabled); +} + +} // namespace + UserPermissionServiceImpl::UserPermissionServiceImpl( policy::ManagementService* management_service, std::unique_ptr<UserDelegate> user_delegate, @@ -53,8 +64,15 @@ return false; } + // Unmanaged profiles are not considered unaffiliated contexts. + bool is_unaffiliated_user = IsDeviceCloudManaged() && + user_delegate_->IsManagedUser() && + !user_delegate_->IsAffiliated(); + bool consent_required_by_specific_policy = - !IsDeviceCloudManaged() && IsConsentFlowPolicyEnabled(); + IsConsentFlowPolicyEnabled() && + (!IsDeviceCloudManaged() || + (IsNewEvSignalsUnaffiliatedEnabled() && is_unaffiliated_user)); bool consent_required_by_dependent_policy = false; std::set<policy::PolicyScope> scopes = @@ -63,7 +81,7 @@ if (IsDeviceCloudManaged()) { // Managed device, only trigger the consent flow if the user is // unaffiliated. - consent_required_by_dependent_policy = !user_delegate_->IsAffiliated(); + consent_required_by_dependent_policy = is_unaffiliated_user; } else { // Unmanaged device. consent_required_by_dependent_policy = true; @@ -90,18 +108,14 @@ return UserPermission::kConsumerUser; } - // User consent is required on Cloud-unmanaged devices. Collection of the - // user's consent happens via its own flow and hooks, so only the resulting - // value needs to be evaluated here. - if (!IsDeviceCloudManaged()) { + // User consent is required on Cloud-unmanaged devices, or in unaffiliated + // contexts. Collection of the user's consent happens via its own flow and + // hooks, so only the resulting value needs to be evaluated here. + if (!IsDeviceCloudManaged() || !user_delegate_->IsAffiliated()) { return HasUserConsented() ? UserPermission::kGranted : UserPermission::kMissingConsent; } - if (!user_delegate_->IsAffiliated()) { - return UserPermission::kUnaffiliated; - } - // At this point, the given user is: // - The same user as the browser user, // - Is managed by an org affiliated with the org managing the browser.
diff --git a/components/device_signals/core/browser/user_permission_service_impl_unittest.cc b/components/device_signals/core/browser/user_permission_service_impl_unittest.cc index 3a8b371..b3618ce0 100644 --- a/components/device_signals/core/browser/user_permission_service_impl_unittest.cc +++ b/components/device_signals/core/browser/user_permission_service_impl_unittest.cc
@@ -5,11 +5,13 @@ #include "components/device_signals/core/browser/user_permission_service_impl.h" #include "base/memory/raw_ptr.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "components/device_signals/core/browser/mock_user_delegate.h" #include "components/device_signals/core/browser/pref_names.h" #include "components/device_signals/core/browser/user_context.h" #include "components/device_signals/core/browser/user_delegate.h" +#include "components/device_signals/core/common/signals_features.h" #include "components/policy/core/common/management/management_service.h" #include "components/policy/core/common/management/scoped_management_service_override_for_testing.h" #include "components/prefs/pref_registry.h" @@ -44,10 +46,14 @@ } // namespace -class UserPermissionServiceImplTest : public testing::Test { +class UserPermissionServiceImplTest : public testing::Test, + public testing::WithParamInterface<bool> { protected: UserPermissionServiceImplTest() { RegisterProfilePrefs(test_prefs_.registry()); + scoped_feature_list_.InitWithFeatureState( + enterprise_signals::features::kNewEvSignalsUnaffiliatedEnabled, + is_new_ev_signals_unaffiliated_enabled()); auto mock_user_delegate = std::make_unique<testing::StrictMock<MockUserDelegate>>(); @@ -84,13 +90,18 @@ .WillOnce(Return(std::move(scopes))); } - void EnableConsentFlowPolicy() { + void EnableConsentFlowPolicy() { SetConsentFlowPolicy(true); } + + void SetConsentFlowPolicy(bool value) { test_prefs_.SetBoolean(prefs::kUnmanagedDeviceSignalsConsentFlowEnabled, - true); + value); } + bool is_new_ev_signals_unaffiliated_enabled() { return GetParam(); } + base::test::TaskEnvironment task_environment_; + base::test::ScopedFeatureList scoped_feature_list_; TestManagementService management_service_; absl::optional<ScopedManagementServiceOverrideForTesting> scoped_override_; raw_ptr<testing::StrictMock<MockUserDelegate>, DanglingUntriaged> @@ -101,22 +112,65 @@ }; // Tests that consent does not need to be collected if it was already given. -TEST_F(UserPermissionServiceImplTest, ShouldCollectConsent_ConsentGiven) { +TEST_P(UserPermissionServiceImplTest, ShouldCollectConsent_ConsentGiven) { SetUserConsentGiven(); EXPECT_FALSE(permission_service_->ShouldCollectConsent()); } +struct DeviceManagedSpecificPolicyTestCase { + bool policy_enabled = false; + bool managed_user = false; + bool is_affiliated = false; + bool should_collect_consent = false; +}; + // Tests that consent does not need to be collected if the device is cloud // managed. -TEST_F(UserPermissionServiceImplTest, ShouldCollectConsent_DeviceCloudManaged) { +TEST_P(UserPermissionServiceImplTest, ShouldCollectConsent_DeviceCloudManaged) { SetDeviceAsCloudManaged(); - SetPolicyScopesNeedingSignals(/*machine_scope=*/false, /*user_scope*/ false); - EXPECT_FALSE(permission_service_->ShouldCollectConsent()); + + std::array<DeviceManagedSpecificPolicyTestCase, 6> test_cases = { + DeviceManagedSpecificPolicyTestCase{ + /*policy_enabled=*/true, /*managed_user=*/true, + /*is_affiliated=*/true, /*should_collect_consent=*/false}, + DeviceManagedSpecificPolicyTestCase{ + /*policy_enabled=*/true, /*managed_user=*/true, + /*is_affiliated=*/false, + /*should_collect_consent=*/is_new_ev_signals_unaffiliated_enabled()}, + DeviceManagedSpecificPolicyTestCase{ + /*policy_enabled=*/true, /*managed_user=*/false, + /*is_affiliated=*/false, /*should_collect_consent=*/false}, + DeviceManagedSpecificPolicyTestCase{ + /*policy_enabled=*/false, /*managed_user=*/true, + /*is_affiliated=*/true, /*should_collect_consent=*/false}, + DeviceManagedSpecificPolicyTestCase{ + /*policy_enabled=*/false, /*managed_user=*/true, + /*is_affiliated=*/false, /*should_collect_consent=*/false}, + DeviceManagedSpecificPolicyTestCase{ + /*policy_enabled=*/false, /*managed_user=*/false, + /*is_affiliated=*/false, /*should_collect_consent=*/false}, + }; + + for (const auto& test_case : test_cases) { + SetPolicyScopesNeedingSignals(/*machine_scope=*/false, + /*user_scope*/ false); + SetConsentFlowPolicy(test_case.policy_enabled); + + EXPECT_CALL(*mock_user_delegate_, IsManagedUser()) + .Times(AnyNumber()) + .WillOnce(Return(test_case.managed_user)); + EXPECT_CALL(*mock_user_delegate_, IsAffiliated()) + .Times(AnyNumber()) + .WillOnce(Return(test_case.is_affiliated)); + + EXPECT_EQ(permission_service_->ShouldCollectConsent(), + test_case.should_collect_consent); + } } // Tests that consent does not need to be collected if the device is not cloud // managed but the "enable consent flow" policy is not enabled. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, ShouldCollectConsent_NoEnableConsentFlowPolicy) { SetUserAsCloudManaged(); SetPolicyScopesNeedingSignals(/*machine_scope=*/false, /*user_scope*/ false); @@ -125,7 +179,7 @@ // Tests that consent needs to be collected if the device is not cloud managed // and the "enable consent flow" policy is enabled. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, ShouldCollectConsent_SpecificPolicy_ManagedUser) { SetUserAsCloudManaged(); EnableConsentFlowPolicy(); @@ -136,40 +190,58 @@ struct DeviceManagedDependentPolicyTestCase { bool machine_scope = false; bool user_scope = false; + bool managed_user = false; bool is_affiliated = false; bool should_collect_consent = false; }; // Tests the behavior of ShouldCollectConsent against all permutations of // dependent policy scope and affiliation. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, ShouldCollectConsent_ManagedDevice_DependentPolicy) { SetDeviceAsCloudManaged(); - std::array<DeviceManagedDependentPolicyTestCase, 8> test_cases = { + // Testing mostly all permutations of possible scenarios. The only special + // property here is `managed_user`, which only make sense to be tested as + // false when both `user_scope` and `is_affiliated` are also false. + std::array<DeviceManagedDependentPolicyTestCase, 10> test_cases = { DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/true, /*user_scope=*/true, /*is_affiliated=*/true, + /*machine_scope=*/true, /*user_scope=*/true, /*managed_user=*/true, + /*is_affiliated=*/true, /*should_collect_consent=*/false}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/true, /*user_scope=*/true, /*is_affiliated=*/false, + /*machine_scope=*/true, /*user_scope=*/true, /*managed_user=*/true, + /*is_affiliated=*/false, /*should_collect_consent=*/true}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/true, /*user_scope=*/false, /*is_affiliated=*/true, + /*machine_scope=*/true, /*user_scope=*/false, /*managed_user=*/true, + /*is_affiliated=*/true, /*should_collect_consent=*/false}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/true, /*user_scope=*/false, /*is_affiliated=*/false, + /*machine_scope=*/true, /*user_scope=*/false, /*managed_user=*/true, + /*is_affiliated=*/false, /*should_collect_consent=*/false}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/false, /*user_scope=*/true, /*is_affiliated=*/true, + /*machine_scope=*/true, /*user_scope=*/false, /*managed_user=*/false, + /*is_affiliated=*/false, /*should_collect_consent=*/false}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/false, /*user_scope=*/true, /*is_affiliated=*/false, + /*machine_scope=*/false, /*user_scope=*/true, /*managed_user=*/true, + /*is_affiliated=*/true, + /*should_collect_consent=*/false}, + DeviceManagedDependentPolicyTestCase{ + /*machine_scope=*/false, /*user_scope=*/true, /*managed_user=*/true, + /*is_affiliated=*/false, /*should_collect_consent=*/true}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/false, /*user_scope=*/false, /*is_affiliated=*/true, + /*machine_scope=*/false, /*user_scope=*/false, /*managed_user=*/true, + /*is_affiliated=*/true, /*should_collect_consent=*/false}, DeviceManagedDependentPolicyTestCase{ - /*machine_scope=*/false, /*user_scope=*/false, + /*machine_scope=*/false, /*user_scope=*/false, /*managed_user=*/true, + /*is_affiliated=*/false, /*should_collect_consent=*/false}, + DeviceManagedDependentPolicyTestCase{ + /*machine_scope=*/false, /*user_scope=*/false, /*managed_user=*/false, /*is_affiliated=*/false, /*should_collect_consent=*/false}, }; @@ -177,6 +249,9 @@ SetPolicyScopesNeedingSignals(test_case.machine_scope, test_case.user_scope); + EXPECT_CALL(*mock_user_delegate_, IsManagedUser()) + .Times(AnyNumber()) + .WillOnce(Return(test_case.managed_user)); EXPECT_CALL(*mock_user_delegate_, IsAffiliated()) .Times(AnyNumber()) .WillOnce(Return(test_case.is_affiliated)); @@ -188,7 +263,7 @@ // Tests that consent should be collected when a dependent policy is enabled on // an unmanaged device. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, ShouldCollectConsent_UnmanagedDevice_DependentPolicy) { SetUserAsCloudManaged(); SetPolicyScopesNeedingSignals(/*machine_scope=*/false, /*user_scope*/ true); @@ -201,7 +276,7 @@ } // namespace // Tests CanUserCollectSignals with a missing user ID. -TEST_F(UserPermissionServiceImplTest, CanUserCollectSignals_EmptyUserId) { +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_EmptyUserId) { SetDeviceAsCloudManaged(); UserContext user_context; @@ -211,7 +286,7 @@ // Tests CanUserCollectSignals with a user ID that does not represent the // current browser user. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_UserId_NotSameUser) { SetDeviceAsCloudManaged(); @@ -228,7 +303,7 @@ // Tests CanUserCollectSignals with a user ID that represents the browser user, // but that user is not managed. -TEST_F(UserPermissionServiceImplTest, CanUserCollectSignals_User_NotManaged) { +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_User_NotManaged) { SetDeviceAsCloudManaged(); UserContext user_context; @@ -244,7 +319,7 @@ // Tests CanUserCollectSignals with a managed user ID but the browser is not // managed and the user has not given consent. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_BrowserNotManaged_NoConsent) { SetUserAsCloudManaged(); @@ -261,7 +336,7 @@ // Tests CanUserCollectSignals with a managed user ID but the browser is not // managed and the user has given consent. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_BrowserNotManaged_WithConsent) { SetUserAsCloudManaged(); SetUserConsentGiven(); @@ -280,7 +355,7 @@ // Tests CanUserCollectSignals with a managed user ID and the browser is // managed, where the user is the same as the profile user but it is not // affiliated with the browser's org. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_BrowserManaged_ProfileUser_Unaffiliated) { SetDeviceAsCloudManaged(); @@ -293,13 +368,13 @@ EXPECT_CALL(*mock_user_delegate_, IsAffiliated()).WillOnce(Return(false)); EXPECT_EQ(permission_service_->CanUserCollectSignals(user_context), - UserPermission::kUnaffiliated); + UserPermission::kMissingConsent); } // Tests CanUserCollectSignals with a managed user ID and the browser is // managed, where the user is the same as the profile user and it is affiliated // with the browser's org. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanUserCollectSignals_BrowserManaged_ProfileUser_Affiliated) { SetDeviceAsCloudManaged(); @@ -318,14 +393,14 @@ // Tests that signals can be collected if the user has already given their // consent. -TEST_F(UserPermissionServiceImplTest, CanCollectSignals_AlreadyConsented) { +TEST_P(UserPermissionServiceImplTest, CanCollectSignals_AlreadyConsented) { SetUserConsentGiven(); EXPECT_EQ(permission_service_->CanCollectSignals(), UserPermission::kGranted); } // Tests that consent is required before allowing to collect signals from an // unmanaged browser. -TEST_F(UserPermissionServiceImplTest, CanCollectSignals_BrowserNotManaged) { +TEST_P(UserPermissionServiceImplTest, CanCollectSignals_BrowserNotManaged) { SetUserAsCloudManaged(); EXPECT_EQ(permission_service_->CanCollectSignals(), UserPermission::kMissingConsent); @@ -333,7 +408,7 @@ // Tests that signals can be collected when on a managed browser in an unmanaged // profile. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanCollectSignals_BrowserManaged_UnmanagedUser) { SetDeviceAsCloudManaged(); @@ -344,7 +419,7 @@ // Tests that signals can be collected when on a managed browser in an // affiliated profile. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanCollectSignals_BrowserManaged_AffiliatedUser) { SetDeviceAsCloudManaged(); @@ -362,7 +437,7 @@ // Tests whether signals can be collected in various unaffiliated context // use-cases. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, CanCollectSignals_BrowserManaged_UnaffiliatedUser) { SetDeviceAsCloudManaged(); @@ -392,7 +467,7 @@ // Tests that the consent flow policy is being observed and can cause the // consent received pref to reset. -TEST_F(UserPermissionServiceImplTest, ResetConsentIfNeeded_PolicyPrefObserver) { +TEST_P(UserPermissionServiceImplTest, ResetConsentIfNeeded_PolicyPrefObserver) { SetUserConsentGiven(); // Enabling the policy should not clear consent. @@ -417,7 +492,7 @@ // Tests that the consent received policy can be reset based on changes in // dependent user-level policies. -TEST_F(UserPermissionServiceImplTest, +TEST_P(UserPermissionServiceImplTest, ResetConsentIfNeeded_DependentPolicyChanged) { std::array<ResetDependentPolicyTestCase, 4> test_cases = { ResetDependentPolicyTestCase{/*machine_scope=*/true, /*user_scope=*/true, @@ -443,4 +518,6 @@ } } +INSTANTIATE_TEST_SUITE_P(, UserPermissionServiceImplTest, testing::Bool()); + } // namespace device_signals
diff --git a/components/device_signals/core/common/signals_features.cc b/components/device_signals/core/common/signals_features.cc index 7cf3e1b..801bddd 100644 --- a/components/device_signals/core/common/signals_features.cc +++ b/components/device_signals/core/common/signals_features.cc
@@ -60,4 +60,8 @@ #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || // BUILDFLAG(IS_CHROMEOS_ASH) +BASE_FEATURE(kNewEvSignalsUnaffiliatedEnabled, + "NewEvSignalsUnaffiliatedEnabled", + base::FEATURE_DISABLED_BY_DEFAULT); + } // namespace enterprise_signals::features
diff --git a/components/device_signals/core/common/signals_features.h b/components/device_signals/core/common/signals_features.h index 5cf33c90..7778076 100644 --- a/components/device_signals/core/common/signals_features.h +++ b/components/device_signals/core/common/signals_features.h
@@ -37,6 +37,10 @@ #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || // BUILDFLAG(IS_CHROMEOS_ASH) +// Feature flag for supporting the new private SecureConnect functions in +// unaffiliated contexts via the consent flow. +BASE_DECLARE_FEATURE(kNewEvSignalsUnaffiliatedEnabled); + } // namespace enterprise_signals::features #endif // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_SIGNALS_FEATURES_H_
diff --git a/components/enterprise/DEPS b/components/enterprise/DEPS index 95d99e6a..25f52d17 100644 --- a/components/enterprise/DEPS +++ b/components/enterprise/DEPS
@@ -11,5 +11,5 @@ "+net", "+services/network/public", "+third_party/protobuf", - "+third_party/content_analysis_sdk" + "+third_party/content_analysis_sdk", ]
diff --git a/components/enterprise/idle/BUILD.gn b/components/enterprise/idle/BUILD.gn new file mode 100644 index 0000000..9cae21f2 --- /dev/null +++ b/components/enterprise/idle/BUILD.gn
@@ -0,0 +1,45 @@ +# 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. + +source_set("idle") { + sources = [ + "action_type.cc", + "action_type.h", + "idle_features.cc", + "idle_features.h", + "idle_pref_names.cc", + "idle_pref_names.h", + "idle_timeout_policy_handler.cc", + "idle_timeout_policy_handler.h", + ] + deps = [ + "//base", + "//components/browsing_data/core", + "//components/policy/core/browser", + "//components/policy/core/common", + "//components/prefs", + "//components/strings", + "//components/sync/base", + ] +} + +source_set("unit_tests") { + testonly = true + + sources = [ "idle_timeout_policy_handler_unittest.cc" ] + deps = [ + ":idle", + "//base", + "//base/test:test_support", + "//components/browsing_data/core", + "//components/policy/core/browser", + "//components/policy/core/common", + "//components/prefs", + "//components/strings", + "//components/sync/base", + "//testing/gmock", + "//testing/gtest", + "//ui/base", + ] +}
diff --git a/components/enterprise/idle/DEPS b/components/enterprise/idle/DEPS new file mode 100644 index 0000000..f6c7f6b --- /dev/null +++ b/components/enterprise/idle/DEPS
@@ -0,0 +1,11 @@ +include_rules = [ + "+components/browsing_data/core", + "+components/strings", + "+components/sync/base", +] + +specific_include_rules = { + "idle_timeout_policy_handler_unittest.cc" : [ + "+ui/base/l10n", + ] +} \ No newline at end of file
diff --git a/components/enterprise/idle/OWNERS b/components/enterprise/idle/OWNERS new file mode 100644 index 0000000..1639e39a --- /dev/null +++ b/components/enterprise/idle/OWNERS
@@ -0,0 +1 @@ +nicolaso@chromium.org \ No newline at end of file
diff --git a/components/enterprise/idle/action_type.cc b/components/enterprise/idle/action_type.cc new file mode 100644 index 0000000..1510c271 --- /dev/null +++ b/components/enterprise/idle/action_type.cc
@@ -0,0 +1,110 @@ + +// 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 "components/enterprise/idle/action_type.h" + +#include <cstring> +#include <regex> +#include <string> +#include <utility> + +#include "base/containers/span.h" +#include "base/functional/bind.h" +#include "base/ranges/algorithm.h" +#include "base/strings/string_util.h" + +#include "base/json/values_util.h" +#include "base/ranges/algorithm.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "base/values.h" + +namespace enterprise_idle { + +namespace { +#if !BUILDFLAG(IS_ANDROID) +const char kCloseBrowsersActionName[] = "close_browsers"; +const char kShowProfilePickerActionName[] = "show_profile_picker"; +#endif // !BUILDFLAG(IS_ANDROID) +const char kClearBrowsingHistoryActionName[] = "clear_browsing_history"; +const char kClearDownloadHistoryActionName[] = "clear_download_history"; +const char kClearCookiesAndOtherSiteDataActionName[] = + "clear_cookies_and_other_site_data"; +const char kClearCachedImagesAndFilesActionName[] = + "clear_cached_images_and_files"; +const char kClearPasswordSigninActionName[] = "clear_password_signin"; +const char kClearAutofillActionName[] = "clear_autofill"; +const char kClearSiteSettingsActionName[] = "clear_site_settings"; +const char kClearHostedAppDataActionName[] = "clear_hosted_app_data"; +const char kReloadPagesActionName[] = "reload_pages"; +} // namespace + +#if !BUILDFLAG(IS_ANDROID) +bool AllowsSyncEnabled(const std::string& name) { + static const char* kActionsAllowedWithSync[] = { + kCloseBrowsersActionName, + kShowProfilePickerActionName, + kClearDownloadHistoryActionName, + kClearCookiesAndOtherSiteDataActionName, + kClearCachedImagesAndFilesActionName, + kReloadPagesActionName, + kClearHostedAppDataActionName}; + return base::ranges::any_of( + base::make_span(kActionsAllowedWithSync), + [&name](const char* allowed_action) { return allowed_action == name; }); +} +#endif //! BUILDFLAG(IS_ANDROID) + +absl::optional<ActionType> NameToActionType(const std::string& name) { +#if !BUILDFLAG(IS_ANDROID) + if (name == kCloseBrowsersActionName) { + return ActionType::kCloseBrowsers; + } + if (name == kShowProfilePickerActionName) { + return ActionType::kShowProfilePicker; + } +#endif // !BUILDFLAG(IS_ANDROID) + if (name == kClearBrowsingHistoryActionName) { + return ActionType::kClearBrowsingHistory; + } + if (name == kClearDownloadHistoryActionName) { + return ActionType::kClearDownloadHistory; + } + if (name == kClearCookiesAndOtherSiteDataActionName) { + return ActionType::kClearCookiesAndOtherSiteData; + } + if (name == kClearCachedImagesAndFilesActionName) { + return ActionType::kClearCachedImagesAndFiles; + } + if (name == kClearPasswordSigninActionName) { + return ActionType::kClearPasswordSignin; + } + if (name == kClearAutofillActionName) { + return ActionType::kClearAutofill; + } + if (name == kClearSiteSettingsActionName) { + return ActionType::kClearSiteSettings; + } + if (name == kClearHostedAppDataActionName) { + return ActionType::kClearHostedAppData; + } + if (name == kReloadPagesActionName) { + return ActionType::kReloadPages; + } + return absl::nullopt; +} + +std::string GetActionBrowsingDataTypeName(const std::string& action) { + // Get the data type to be cleared if the action is to clear browsig data. + const char kPrefix[] = "clear_"; + if (!base::StartsWith(action, kPrefix, base::CompareCase::SENSITIVE)) { + return std::string(); + } + return action.substr(std::strlen(kPrefix)); +} + +} // namespace enterprise_idle
diff --git a/components/enterprise/idle/action_type.h b/components/enterprise/idle/action_type.h new file mode 100644 index 0000000..5e5b2bd --- /dev/null +++ b/components/enterprise/idle/action_type.h
@@ -0,0 +1,49 @@ +// 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 COMPONENTS_ENTERPRISE_IDLE_ACTION_TYPE_H_ +#define COMPONENTS_ENTERPRISE_IDLE_ACTION_TYPE_H_ + +#include <string> + +#include "base/values.h" +#include "build/build_config.h" + +namespace enterprise_idle { + +// Action types supported by IdleTimeoutActions. +// +// Actions run in order, based on their numerical value. Lower values run first. +// Keep this enum sorted by priority. +enum class ActionType { + kShowDialog = 0, // Not an IdleTimeoutAction value. Added as a side-effect. +#if !BUILDFLAG(IS_ANDROID) + kCloseBrowsers = 1, + kShowProfilePicker = 2, +#endif // !BUILDFLAG(IS_ANDROID) + kClearBrowsingHistory = 3, + kClearDownloadHistory, + kClearCookiesAndOtherSiteData, + kClearCachedImagesAndFiles, + kClearPasswordSignin, + kClearAutofill, + kClearSiteSettings, + kClearHostedAppData, + kReloadPages, + kShowBubble, // Not an IdleTimeoutAction value. Added as a side-effect. +}; + +// Checks if the action type does not require sync types to be disabled. +bool AllowsSyncEnabled(const std::string& name); + +// Returns the idle timeout action type for an action string. +absl::optional<ActionType> NameToActionType(const std::string& name); + +// Returns the name of the browsing data type that should be cleared given +// `clear_*` action name. +std::string GetActionBrowsingDataTypeName(const std::string& action); + +} // namespace enterprise_idle + +#endif // COMPONENTS_ENTERPRISE_IDLE_ACTION_TYPE_H_
diff --git a/chrome/browser/enterprise/idle/idle_features.cc b/components/enterprise/idle/idle_features.cc similarity index 82% rename from chrome/browser/enterprise/idle/idle_features.cc rename to components/enterprise/idle/idle_features.cc index 95d97df..28d8381 100644 --- a/chrome/browser/enterprise/idle/idle_features.cc +++ b/components/enterprise/idle/idle_features.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/enterprise/idle/idle_features.h" +#include "components/enterprise/idle/idle_features.h" namespace enterprise_idle {
diff --git a/chrome/browser/enterprise/idle/idle_features.h b/components/enterprise/idle/idle_features.h similarity index 65% rename from chrome/browser/enterprise/idle/idle_features.h rename to components/enterprise/idle/idle_features.h index 710579b..179f08f 100644 --- a/chrome/browser/enterprise/idle/idle_features.h +++ b/components/enterprise/idle/idle_features.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_FEATURES_H_ -#define CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_FEATURES_H_ +#ifndef COMPONENTS_ENTERPRISE_IDLE_IDLE_FEATURES_H_ +#define COMPONENTS_ENTERPRISE_IDLE_IDLE_FEATURES_H_ #include "base/feature_list.h" @@ -14,4 +14,4 @@ } // namespace enterprise_idle -#endif // CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_FEATURES_H_ +#endif // COMPONENTS_ENTERPRISE_IDLE_IDLE_FEATURES_H_
diff --git a/components/enterprise/idle/idle_pref_names.cc b/components/enterprise/idle/idle_pref_names.cc new file mode 100644 index 0000000..a55045d3 --- /dev/null +++ b/components/enterprise/idle/idle_pref_names.cc
@@ -0,0 +1,19 @@ +// 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 "components/enterprise/idle/idle_pref_names.h" + +namespace enterprise_idle::prefs { +// Number of minutes of inactivity before running actions from +// kIdleTimeoutActions. Controlled via the IdleTimeout policy. +const char kIdleTimeout[] = "idle_timeout"; + +// Actions to run when the idle timeout is reached. Controller via the +// IdleTimeoutActions policy. +const char kIdleTimeoutActions[] = "idle_timeout_actions"; + +// If true, show the IdleTimeout bubble when Chrome starts. +const char kIdleTimeoutShowBubbleOnStartup[] = + "idle_timeout_show_bubble_on_startup"; +} // namespace enterprise_idle::prefs
diff --git a/components/enterprise/idle/idle_pref_names.h b/components/enterprise/idle/idle_pref_names.h new file mode 100644 index 0000000..463251e --- /dev/null +++ b/components/enterprise/idle/idle_pref_names.h
@@ -0,0 +1,14 @@ +// 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 COMPONENTS_ENTERPRISE_IDLE_IDLE_PREF_NAMES_H_ +#define COMPONENTS_ENTERPRISE_IDLE_IDLE_PREF_NAMES_H_ + +namespace enterprise_idle::prefs { +extern const char kIdleTimeout[]; +extern const char kIdleTimeoutActions[]; +extern const char kIdleTimeoutShowBubbleOnStartup[]; +} // namespace enterprise_idle::prefs + +#endif // COMPONENTS_ENTERPRISE_IDLE_IDLE_PREF_NAMES_H_
diff --git a/chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc b/components/enterprise/idle/idle_timeout_policy_handler.cc similarity index 70% rename from chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc rename to components/enterprise/idle/idle_timeout_policy_handler.cc index a92dade..f840847 100644 --- a/chrome/browser/enterprise/idle/idle_timeout_policy_handler.cc +++ b/components/enterprise/idle/idle_timeout_policy_handler.cc
@@ -2,25 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/enterprise/idle/idle_timeout_policy_handler.h" +#include "components/enterprise/idle/idle_timeout_policy_handler.h" -#include <cstring> -#include <regex> #include <string> -#include "base/containers/span.h" #include "base/json/values_util.h" -#include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/browser/enterprise/idle/action.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/common/pref_names.h" #include "components/browsing_data/core/browsing_data_policies_utils.h" +#include "components/enterprise/idle/action_type.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/policy/core/browser/configuration_policy_handler.h" #include "components/policy/core/browser/policy_error_map.h" #include "components/policy/core/common/policy_logger.h" @@ -34,99 +29,20 @@ namespace { -#if !BUILDFLAG(IS_ANDROID) -const char kCloseBrowsersActionName[] = "close_browsers"; -const char kShowProfilePickerActionName[] = "show_profile_picker"; -#endif // !BUILDFLAG(IS_ANDROID) -const char kClearBrowsingHistoryActionName[] = "clear_browsing_history"; -const char kClearDownloadHistoryActionName[] = "clear_download_history"; -const char kClearCookiesAndOtherSiteDataActionName[] = - "clear_cookies_and_other_site_data"; -const char kClearCachedImagesAndFilesActionName[] = - "clear_cached_images_and_files"; -const char kClearPasswordSigninActionName[] = "clear_password_signin"; -const char kClearAutofillActionName[] = "clear_autofill"; -const char kClearSiteSettingsActionName[] = "clear_site_settings"; -const char kClearHostedAppDataActionName[] = "clear_hosted_app_data"; -const char kReloadPagesActionName[] = "reload_pages"; - // If `other_policy_name` is unset, adds an error to `errors` and returns false. bool CheckOtherPolicySet(const policy::PolicyMap& policies, const std::string& this_policy_name, const std::string& other_policy_name, policy::PolicyErrorMap* errors) { - if (policies.GetValueUnsafe(other_policy_name)) + if (policies.GetValueUnsafe(other_policy_name)) { return true; + } errors->AddError(this_policy_name, IDS_POLICY_DEPENDENCY_ERROR_ANY_VALUE, other_policy_name); return false; } -#if !BUILDFLAG(IS_ANDROID) -bool RequiresSyncDisabled(const std::string& name) { - static const char* kActionsAllowedWithSync[] = { - kCloseBrowsersActionName, - kShowProfilePickerActionName, - kClearDownloadHistoryActionName, - kClearCookiesAndOtherSiteDataActionName, - kClearCachedImagesAndFilesActionName, - kReloadPagesActionName, - kClearHostedAppDataActionName}; - return !base::ranges::any_of( - base::make_span(kActionsAllowedWithSync), - [&name](const char* s) { return !std::strcmp(s, name.c_str()); }); -} -#endif //! BUILDFLAG(IS_ANDROID) - -absl::optional<ActionType> NameToActionType(const std::string& name) { -#if !BUILDFLAG(IS_ANDROID) - if (name == kCloseBrowsersActionName) { - return ActionType::kCloseBrowsers; - } - if (name == kShowProfilePickerActionName) { - return ActionType::kShowProfilePicker; - } -#endif // !BUILDFLAG(IS_ANDROID) - if (name == kClearBrowsingHistoryActionName) { - return ActionType::kClearBrowsingHistory; - } - if (name == kClearDownloadHistoryActionName) { - return ActionType::kClearDownloadHistory; - } - if (name == kClearCookiesAndOtherSiteDataActionName) { - return ActionType::kClearCookiesAndOtherSiteData; - } - if (name == kClearCachedImagesAndFilesActionName) { - return ActionType::kClearCachedImagesAndFiles; - } - if (name == kClearPasswordSigninActionName) { - return ActionType::kClearPasswordSignin; - } - if (name == kClearAutofillActionName) { - return ActionType::kClearAutofill; - } - if (name == kClearSiteSettingsActionName) { - return ActionType::kClearSiteSettings; - } - if (name == kClearHostedAppDataActionName) { - return ActionType::kClearHostedAppData; - } - if (name == kReloadPagesActionName) { - return ActionType::kReloadPages; - } - return absl::nullopt; -} - -std::string GetActionBrowsingDataTypeName(const std::string& action) { - // Get the data type to be cleared if the action is to clear browsig data. - const char kPrefix[] = "clear_"; - if (!base::StartsWith(action, kPrefix, base::CompareCase::SENSITIVE)) { - return std::string(); - } - return action.substr(std::strlen(kPrefix)); -} - } // namespace IdleTimeoutPolicyHandler::IdleTimeoutPolicyHandler() @@ -246,7 +162,7 @@ policies.GetValue(policy_name(), base::Value::Type::LIST); DCHECK(value); for (const base::Value& action : value->GetList()) { - if (action.is_string() && RequiresSyncDisabled(action.GetString())) { + if (action.is_string() && !AllowsSyncEnabled(action.GetString())) { invalid_actions.push_back(action.GetString()); } }
diff --git a/chrome/browser/enterprise/idle/idle_timeout_policy_handler.h b/components/enterprise/idle/idle_timeout_policy_handler.h similarity index 90% rename from chrome/browser/enterprise/idle/idle_timeout_policy_handler.h rename to components/enterprise/idle/idle_timeout_policy_handler.h index 0fd1443..38f1fde 100644 --- a/chrome/browser/enterprise/idle/idle_timeout_policy_handler.h +++ b/components/enterprise/idle/idle_timeout_policy_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_TIMEOUT_POLICY_HANDLER_H_ -#define CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_TIMEOUT_POLICY_HANDLER_H_ +#ifndef COMPONENTS_ENTERPRISE_IDLE_IDLE_TIMEOUT_POLICY_HANDLER_H_ +#define COMPONENTS_ENTERPRISE_IDLE_IDLE_TIMEOUT_POLICY_HANDLER_H_ #include "components/policy/core/browser/configuration_policy_handler.h" #include "components/sync/base/user_selectable_type.h" @@ -62,4 +62,4 @@ } // namespace enterprise_idle -#endif // CHROME_BROWSER_ENTERPRISE_IDLE_IDLE_TIMEOUT_POLICY_HANDLER_H_ +#endif // COMPONENTS_ENTERPRISE_IDLE_IDLE_TIMEOUT_POLICY_HANDLER_H_
diff --git a/chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc b/components/enterprise/idle/idle_timeout_policy_handler_unittest.cc similarity index 98% rename from chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc rename to components/enterprise/idle/idle_timeout_policy_handler_unittest.cc index ce76741..8b2a61e 100644 --- a/chrome/browser/enterprise/idle/idle_timeout_policy_handler_unittest.cc +++ b/components/enterprise/idle/idle_timeout_policy_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/enterprise/idle/idle_timeout_policy_handler.h" +#include "components/enterprise/idle/idle_timeout_policy_handler.h" #include <iterator> #include <string> @@ -14,9 +14,9 @@ #include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "base/values.h" -#include "chrome/browser/enterprise/idle/action.h" -#include "chrome/common/pref_names.h" #include "components/browsing_data/core/features.h" +#include "components/enterprise/idle/action_type.h" +#include "components/enterprise/idle/idle_pref_names.h" #include "components/policy/core/browser/configuration_policy_handler.h" #include "components/policy/core/browser/policy_error_map.h" #include "components/policy/core/common/policy_map.h" @@ -63,8 +63,9 @@ } void CheckAndApplyPolicySettings() { - if (CheckPolicySettings()) + if (CheckPolicySettings()) { ApplyPolicySettings(); + } } PrefValueMap& prefs() { return prefs_; }
diff --git a/components/exo/data_device.h b/components/exo/data_device.h index 302e808af7..999f43c 100644 --- a/components/exo/data_device.h +++ b/components/exo/data_device.h
@@ -90,7 +90,8 @@ void PerformDropOrExitDrag(base::ScopedClosureRunner exit_drag, ui::mojom::DragOperation& output_drag_op); - const raw_ptr<DataDeviceDelegate, ExperimentalAsh> delegate_; + const raw_ptr<DataDeviceDelegate, DanglingUntriaged | ExperimentalAsh> + delegate_; const raw_ptr<Seat, ExperimentalAsh> seat_; std::unique_ptr<ScopedDataOffer> data_offer_; std::unique_ptr<ScopedSurface> focused_surface_;
diff --git a/components/feedback/content/feedback_uploader_factory.cc b/components/feedback/content/feedback_uploader_factory.cc index 517d98e8..c80483e 100644 --- a/components/feedback/content/feedback_uploader_factory.cc +++ b/components/feedback/content/feedback_uploader_factory.cc
@@ -49,12 +49,13 @@ FeedbackUploaderFactory::~FeedbackUploaderFactory() {} -KeyedService* FeedbackUploaderFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +FeedbackUploaderFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { // The returned FeedbackUploader lifetime is bound to that of BrowserContext // by the KeyedServiceFactory infrastructure. The FeedbackUploader will be // destroyed before the BrowserContext, thus base::Unretained() usage is safe. - return new FeedbackUploader( + return std::make_unique<FeedbackUploader>( context->IsOffTheRecord(), context->GetPath(), base::BindOnce(&CreateURLLoaderFactoryForBrowserContext, base::Unretained(context)));
diff --git a/components/feedback/content/feedback_uploader_factory.h b/components/feedback/content/feedback_uploader_factory.h index 77b7fd2..cd4af800 100644 --- a/components/feedback/content/feedback_uploader_factory.h +++ b/components/feedback/content/feedback_uploader_factory.h
@@ -43,7 +43,7 @@ FeedbackUploaderFactory(); // BrowserContextKeyedServiceFactory overrides: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/components/media_router/browser/android/flinging_controller_bridge.cc b/components/media_router/browser/android/flinging_controller_bridge.cc index b76bc3c..b7e44f60 100644 --- a/components/media_router/browser/android/flinging_controller_bridge.cc +++ b/components/media_router/browser/android/flinging_controller_bridge.cc
@@ -105,19 +105,19 @@ switch (player_state) { case PLAYER_STATE_UNKOWN: - status.state = media::MediaStatus::State::UNKNOWN; + status.state = media::MediaStatus::State::kUnknown; break; case PLAYER_STATE_PLAYING: - status.state = media::MediaStatus::State::PLAYING; + status.state = media::MediaStatus::State::kPlaying; break; case PLAYER_STATE_PAUSED: - status.state = media::MediaStatus::State::PAUSED; + status.state = media::MediaStatus::State::kPaused; break; case PLAYER_STATE_BUFFERING: - status.state = media::MediaStatus::State::BUFFERING; + status.state = media::MediaStatus::State::kBuffering; break; case PLAYER_STATE_IDLE: - status.state = media::MediaStatus::State::STOPPED; + status.state = media::MediaStatus::State::kStopped; int idle_reason = Java_MediaStatusBridge_idleReason(env, j_status); status.reached_end_of_stream = (idle_reason == IDLE_REASON_FINISHED); break;
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index 21da0f5..735d7b8 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -1343,6 +1343,10 @@ auto log_histogram_writer = std::make_unique<MetricsLogHistogramWriter>( initial_stability_log.get(), base::Histogram::kUmaStabilityHistogramFlag); + // Add a beacon to this record to indicate that it's part of the initial + // stability log. + UMA_STABILITY_HISTOGRAM_BOOLEAN("UMA.InitialStabilityRecordBeacon", true); + // Let metrics providers provide histogram snapshots independently if they // have any. This is done synchronously. delegating_provider_.RecordInitialHistogramSnapshots(
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc index b7581fc..12558ed 100644 --- a/components/metrics/metrics_service_unittest.cc +++ b/components/metrics/metrics_service_unittest.cc
@@ -574,6 +574,8 @@ EXPECT_EQ(0, uma_log.user_action_event_size()); EXPECT_EQ(0, uma_log.omnibox_event_size()); CheckForNonStabilityHistograms(uma_log); + EXPECT_EQ( + 1, GetHistogramSampleCount(uma_log, "UMA.InitialStabilityRecordBeacon")); // As there wasn't an unclean shutdown, no browser crash samples should have // been emitted. @@ -864,6 +866,8 @@ EXPECT_EQ(0, uma_log.user_action_event_size()); EXPECT_EQ(0, uma_log.omnibox_event_size()); CheckForNonStabilityHistograms(uma_log); + EXPECT_EQ( + 1, GetHistogramSampleCount(uma_log, "UMA.InitialStabilityRecordBeacon")); // Verify that the histograms emitted by the test provider made it into the // log.
diff --git a/components/metrics/structured/BUILD.gn b/components/metrics/structured/BUILD.gn index 2b03ec26..f08d1d12 100644 --- a/components/metrics/structured/BUILD.gn +++ b/components/metrics/structured/BUILD.gn
@@ -14,7 +14,6 @@ "external_metrics.h", "key_data.cc", "key_data.h", - "key_data_provider.h", "persistent_proto.cc", "persistent_proto.h", "reporting/structured_metrics_log_metrics.cc", @@ -227,8 +226,6 @@ static_library("test_support") { testonly = true sources = [ - "test/test_key_data_provider.cc", - "test/test_key_data_provider.h", "test/test_structured_metrics_provider.cc", "test/test_structured_metrics_provider.h", ] @@ -257,7 +254,6 @@ ":structured", ":structured_events", ":structured_metrics_validator", - ":test_support", "//base", "//base/test:test_support", "//components/metrics",
diff --git a/components/metrics/structured/key_data_provider.h b/components/metrics/structured/key_data_provider.h deleted file mode 100644 index c67e155d..0000000 --- a/components/metrics/structured/key_data_provider.h +++ /dev/null
@@ -1,55 +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. - -#ifndef COMPONENTS_METRICS_STRUCTURED_KEY_DATA_PROVIDER_H_ -#define COMPONENTS_METRICS_STRUCTURED_KEY_DATA_PROVIDER_H_ - -#include "components/metrics/structured/key_data.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -namespace metrics::structured { - -// Interface to provide key data to be used for hashing projects. -// -// There are two types of keys: device keys and profile keys. Device keys will -// be ready only InitializeDeviceKey has been called while profile keys should -// be ready once InitializeProfileKey has been called. -class KeyDataProvider { - public: - KeyDataProvider() = default; - - KeyDataProvider(const KeyDataProvider& key_data_provider) = delete; - KeyDataProvider& operator=(const KeyDataProvider& key_data_provider) = delete; - - virtual ~KeyDataProvider() = default; - - // Initializes the device key data. - virtual void InitializeDeviceKey(base::OnceClosure callback) = 0; - - // Called whenever a profile key should be initialized. - virtual void InitializeProfileKey(const base::FilePath& profile_path, - base::OnceClosure callback) = 0; - - // Returns the device key data. - // - // Returns nullptr if InitializeDeviceKey() has not been called or is in - // progress. - virtual KeyData* GetDeviceKeyData() = 0; - - // Returns the profile key data, if available. A call to HasProfileKey() - // should guarantee that this value will not be nullptr. - // - // Returns nullptr otherwise. - virtual KeyData* GetProfileKeyData() = 0; - - // Deletes all key data associated with the provider. - virtual void Purge() = 0; - - virtual bool HasProfileKey() = 0; - virtual bool HasDeviceKey() = 0; -}; - -} // namespace metrics::structured - -#endif // COMPONENTS_METRICS_STRUCTURED_KEY_DATA_PROVIDER_H_
diff --git a/components/metrics/structured/structured_metrics_provider_unittest.cc b/components/metrics/structured/structured_metrics_provider_unittest.cc index 48c408a..fac1220f 100644 --- a/components/metrics/structured/structured_metrics_provider_unittest.cc +++ b/components/metrics/structured/structured_metrics_provider_unittest.cc
@@ -22,7 +22,6 @@ #include "components/metrics/structured/structured_events.h" #include "components/metrics/structured/structured_metrics_features.h" #include "components/metrics/structured/structured_metrics_recorder.h" -#include "components/metrics/structured/test/test_key_data_provider.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" @@ -102,11 +101,9 @@ system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); // Create a system profile, normally done by ChromeMetricsServiceClient. structured_metrics_recorder_ = std::unique_ptr<StructuredMetricsRecorder>( - new StructuredMetricsRecorder(/*write_delay=*/base::Seconds(0), + new StructuredMetricsRecorder(DeviceKeyFilePath(), + /*write_delay=*/base::Seconds(0), system_profile_provider_.get())); - structured_metrics_recorder_->InitializeKeyDataProvider( - std::make_unique<TestKeyDataProvider>(DeviceKeyFilePath(), - ProfileKeyFilePath())); // Create the provider, normally done by the ChromeMetricsServiceClient. provider_ = std::unique_ptr<StructuredMetricsProvider>( new StructuredMetricsProvider(
diff --git a/components/metrics/structured/structured_metrics_recorder.cc b/components/metrics/structured/structured_metrics_recorder.cc index 32487b3..08e948af 100644 --- a/components/metrics/structured/structured_metrics_recorder.cc +++ b/components/metrics/structured/structured_metrics_recorder.cc
@@ -43,17 +43,26 @@ int StructuredMetricsRecorder::kMaxEventsPerUpload = 100; +char StructuredMetricsRecorder::kProfileKeyDataPath[] = + "structured_metrics/keys"; + +char StructuredMetricsRecorder::kDeviceKeyDataPath[] = + "/var/lib/metrics/structured/chromium/keys"; + char StructuredMetricsRecorder::kUnsentLogsPath[] = "structured_metrics/events"; StructuredMetricsRecorder::StructuredMetricsRecorder( raw_ptr<metrics::MetricsProvider> system_profile_provider) - : StructuredMetricsRecorder(base::Milliseconds(kSaveDelayMs), + : StructuredMetricsRecorder(base::FilePath(kDeviceKeyDataPath), + base::Milliseconds(kSaveDelayMs), system_profile_provider) {} StructuredMetricsRecorder::StructuredMetricsRecorder( + const base::FilePath& device_key_path, base::TimeDelta write_delay, raw_ptr<metrics::MetricsProvider> system_profile_provider) - : write_delay_(write_delay), + : device_key_path_(device_key_path), + write_delay_(write_delay), system_profile_provider_(system_profile_provider) { DCHECK(system_profile_provider_); Recorder::GetInstance()->AddObserver(this); @@ -123,32 +132,14 @@ Recorder::GetInstance()->OnProvideIndependentMetrics(&uma_proto); } -void StructuredMetricsRecorder::InitializeKeyDataProvider( - std::unique_ptr<KeyDataProvider> key_data_provider) { - key_data_provider_ = std::move(key_data_provider); - - key_data_provider_->InitializeDeviceKey( - base::BindOnce(&StructuredMetricsRecorder::OnDeviceKeyDataInitialized, - weak_factory_.GetWeakPtr())); - - external_metrics_ = std::make_unique<ExternalMetrics>( - base::FilePath(kExternalMetricsDir), - base::Minutes(kExternalMetricsIntervalMins), - base::BindRepeating( - &StructuredMetricsRecorder::OnExternalMetricsCollected, - weak_factory_.GetWeakPtr())); -} - -void StructuredMetricsRecorder::OnDeviceKeyDataInitialized() { +void StructuredMetricsRecorder::OnKeyDataInitialized() { DCHECK(base::CurrentUIThread::IsSet()); - UpdateAndCheckInitState(); -} - -void StructuredMetricsRecorder::OnProfileKeyDataInitialized() { - DCHECK(base::CurrentUIThread::IsSet()); - - UpdateAndCheckInitState(); + ++init_count_; + if (init_count_ == kTargetInitCount) { + init_state_ = InitState::kInitialized; + HashUnhashedEventsAndPersist(); + } } void StructuredMetricsRecorder::OnRead(const ReadStatus status) { @@ -166,7 +157,11 @@ break; } - UpdateAndCheckInitState(); + ++init_count_; + if (init_count_ == kTargetInitCount) { + init_state_ = InitState::kInitialized; + HashUnhashedEventsAndPersist(); + } } void StructuredMetricsRecorder::OnWrite(const WriteStatus status) { @@ -204,12 +199,11 @@ if (!is_init_state(InitState::kInitialized)) { return; } - DCHECK(IsDeviceKeyDataInitialized()); - DCHECK(IsProfileKeyDataInitialized()); - DCHECK(events_); + DCHECK(events_ && profile_key_data_ && device_key_data_); events_->Purge(); - key_data_provider_->Purge(); + profile_key_data_->Purge(); + device_key_data_->Purge(); } void StructuredMetricsRecorder::OnProfileAdded( @@ -225,9 +219,14 @@ } init_state_ = InitState::kProfileAdded; - key_data_provider_->InitializeProfileKey( - profile_path, - base::BindOnce(&StructuredMetricsRecorder::OnProfileKeyDataInitialized, + profile_key_data_ = std::make_unique<KeyData>( + profile_path.Append(kProfileKeyDataPath), write_delay_, + base::BindOnce(&StructuredMetricsRecorder::OnKeyDataInitialized, + weak_factory_.GetWeakPtr())); + + device_key_data_ = std::make_unique<KeyData>( + base::FilePath(device_key_path_), write_delay_, + base::BindOnce(&StructuredMetricsRecorder::OnKeyDataInitialized, weak_factory_.GetWeakPtr())); events_ = std::make_unique<PersistentProto<EventsProto>>( @@ -237,6 +236,13 @@ base::BindRepeating(&StructuredMetricsRecorder::OnWrite, weak_factory_.GetWeakPtr())); + external_metrics_ = std::make_unique<ExternalMetrics>( + base::FilePath(kExternalMetricsDir), + base::Minutes(kExternalMetricsIntervalMins), + base::BindRepeating( + &StructuredMetricsRecorder::OnExternalMetricsCollected, + weak_factory_.GetWeakPtr())); + if (recording_enabled_) { external_metrics_->EnableRecording(); } @@ -265,8 +271,8 @@ return; } - DCHECK(IsDeviceKeyDataInitialized()); - DCHECK(IsProfileKeyDataInitialized()); + DCHECK(profile_key_data_->is_initialized()); + DCHECK(device_key_data_->is_initialized()); RecordEvent(event); @@ -279,20 +285,16 @@ if (init_state_ != InitState::kInitialized) { return absl::nullopt; } - - KeyData* device_key_data = key_data_provider_->GetDeviceKeyData(); - KeyData* profile_key_data = key_data_provider_->GetProfileKeyData(); - - DCHECK(IsDeviceKeyDataInitialized()); - DCHECK(IsProfileKeyDataInitialized()); + DCHECK(profile_key_data_->is_initialized()); + DCHECK(device_key_data_->is_initialized()); // |project_name_hash| could store its keys in either the profile or device // key data, so check both. As they cannot both contain the same name hash, // at most one will return a non-nullopt value. absl::optional<int> profile_day = - profile_key_data->LastKeyRotation(project_name_hash); + profile_key_data_->LastKeyRotation(project_name_hash); absl::optional<int> device_day = - device_key_data->LastKeyRotation(project_name_hash); + device_key_data_->LastKeyRotation(project_name_hash); DCHECK(!(profile_day && device_day)); return profile_day ? profile_day : device_day; } @@ -355,14 +357,6 @@ weak_factory_.GetWeakPtr())); } -void StructuredMetricsRecorder::SetOnReadyToRecord(base::OnceClosure callback) { - on_ready_callback_ = std::move(callback); - - if (init_state_ == InitState::kInitialized) { - std::move(on_ready_callback_).Run(); - } -} - void StructuredMetricsRecorder::RecordEventBeforeInitialization( const Event& event) { DCHECK_NE(init_state_, InitState::kInitialized); @@ -370,13 +364,6 @@ } void StructuredMetricsRecorder::RecordEvent(const Event& event) { - DCHECK(IsDeviceKeyDataInitialized()); - DCHECK(IsProfileKeyDataInitialized()); - - // Retrieve keys. - KeyData* device_key_data = key_data_provider_->GetDeviceKeyData(); - KeyData* profile_key_data = key_data_provider_->GetProfileKeyData(); - // Validates the event. If valid, retrieve the metadata associated // with the event. auto maybe_project_validator = @@ -436,18 +423,18 @@ event_sequence_metadata->set_event_unique_id( base::HashMetricName(event.event_sequence_metadata().event_unique_id)); event_proto->set_device_project_id( - device_key_data->Id(project_validator->project_hash(), - project_validator->key_rotation_period())); + device_key_data_.get()->Id(project_validator->project_hash(), + project_validator->key_rotation_period())); event_proto->set_user_project_id( - profile_key_data->Id(project_validator->project_hash(), - project_validator->key_rotation_period())); + profile_key_data_.get()->Id(project_validator->project_hash(), + project_validator->key_rotation_period())); } // Choose which KeyData to use for this event. KeyData* key_data; switch (project_validator->id_scope()) { case IdScope::kPerProfile: - key_data = profile_key_data; + key_data = profile_key_data_.get(); break; case IdScope::kPerDevice: // For event sequence, use the profile key for now to hash strings. @@ -457,9 +444,9 @@ // events like structured metrics, remove this. if (project_validator->event_type() == StructuredEventProto_EventType_SEQUENCE) { - key_data = profile_key_data; + key_data = profile_key_data_.get(); } else { - key_data = device_key_data; + key_data = device_key_data_.get(); } break; default: @@ -590,23 +577,4 @@ disallowed_projects_.insert(project_name_hash); } -bool StructuredMetricsRecorder::IsDeviceKeyDataInitialized() { - return key_data_provider_ && key_data_provider_->GetDeviceKeyData() && - key_data_provider_->GetDeviceKeyData()->is_initialized(); -} - -bool StructuredMetricsRecorder::IsProfileKeyDataInitialized() { - return key_data_provider_ && key_data_provider_->GetProfileKeyData() && - key_data_provider_->GetProfileKeyData()->is_initialized(); -} - -void StructuredMetricsRecorder::UpdateAndCheckInitState() { - ++init_count_; - if (init_count_ == kTargetInitCount) { - init_state_ = InitState::kInitialized; - HashUnhashedEventsAndPersist(); - std::move(on_ready_callback_).Run(); - } -} - } // namespace metrics::structured
diff --git a/components/metrics/structured/structured_metrics_recorder.h b/components/metrics/structured/structured_metrics_recorder.h index f7034d84..c988b57 100644 --- a/components/metrics/structured/structured_metrics_recorder.h +++ b/components/metrics/structured/structured_metrics_recorder.h
@@ -15,7 +15,6 @@ #include "components/metrics/structured/event.h" #include "components/metrics/structured/external_metrics.h" #include "components/metrics/structured/key_data.h" -#include "components/metrics/structured/key_data_provider.h" #include "components/metrics/structured/project_validator.h" #include "components/metrics/structured/recorder.h" @@ -75,9 +74,6 @@ // fields. void ProvideEventMetrics(ChromeUserMetricsExtension& uma_proto); - void InitializeKeyDataProvider( - std::unique_ptr<KeyDataProvider> key_data_provider); - bool can_provide_metrics() const { return recording_enabled() && is_init_state(InitState::kInitialized); } @@ -86,12 +82,11 @@ EventsProto* events() { return events_->get(); } protected: - friend class TestStructuredMetricsProvider; - // Should only be used for tests. // // TODO(crbug/1350322): Use this ctor to replace existing ctor. StructuredMetricsRecorder( + const base::FilePath& device_key_path, base::TimeDelta write_delay, raw_ptr<metrics::MetricsProvider> system_profile_provider); @@ -110,19 +105,15 @@ // have been read, the provider has been initialized. enum class InitState { kUninitialized = 1, - // Set once InitializeKeyDataProvider has been called. - kKeyDataInitialized = 2, // Set after we observe the recorder, which happens on construction. - kProfileAdded = 3, + kProfileAdded = 2, // Set after all key and event files are read from disk. - kInitialized = 4, + kInitialized = 3, }; bool is_init_state(InitState state) const { return init_state_ == state; } - void OnDeviceKeyDataInitialized(); - void OnProfileKeyDataInitialized(); - + void OnKeyDataInitialized(); void OnRead(ReadStatus status); void OnWrite(WriteStatus status); void OnExternalMetricsCollected(const EventsProto& events); @@ -136,7 +127,6 @@ void WriteNowForTest(); void SetExternalMetricsDirForTest(const base::FilePath& dir); - void SetOnReadyToRecord(base::OnceClosure callback); // Records events before |init_state_| is kInitialized. void RecordEventBeforeInitialization(const Event& event); @@ -163,16 +153,19 @@ // Adds a project to the diallowed list for testing. void AddDisallowedProjectForTest(uint64_t project_name_hash); - bool IsDeviceKeyDataInitialized(); - bool IsProfileKeyDataInitialized(); - - // Increments |init_count_| and checks if the recorder is ready. - void UpdateAndCheckInitState(); - // Beyond this number of logging events between successive calls to // ProvideCurrentSessionData, we stop recording events. static int kMaxEventsPerUpload; + // The path used to store per-profile keys. Relative to the user's + // cryptohome. This file is created by chromium. + static char kProfileKeyDataPath[]; + + // The path used to store per-device keys. This file is created by tmpfiles.d + // on start and has its permissions and ownership set such that it is writable + // by chronos. + static char kDeviceKeyDataPath[]; + // The directory used to store unsent logs. Relative to the user's cryptohome. // This file is created by chromium. static char kUnsentLogsPath[]; @@ -219,12 +212,15 @@ // On-device storage within the user's cryptohome for unsent logs. std::unique_ptr<PersistentProto<EventsProto>> events_; - // Key data provider that provides device and profile keys. - std::unique_ptr<KeyDataProvider> key_data_provider_; - // Store for events that were recorded before user/device keys are loaded. std::deque<Event> unhashed_events_; + // Storage for all event's keys, and hashing logic for values. This stores + // keys on disk. |profile_key_data_| stores keys for per-profile projects, + // and |device_key_data_| stores keys for per-device projects. + std::unique_ptr<KeyData> profile_key_data_; + std::unique_ptr<KeyData> device_key_data_; + // Whether the system profile has been initialized. bool system_profile_initialized_ = false; @@ -247,9 +243,6 @@ // upload. This is only incremented if events were added by the scan. int external_metrics_scans_ = 0; - // Callback to be made once recorder is ready to persist events to disk. - base::OnceClosure on_ready_callback_ = base::DoNothing(); - base::WeakPtrFactory<StructuredMetricsRecorder> weak_factory_{this}; }; } // namespace metrics::structured
diff --git a/components/metrics/structured/structured_metrics_recorder_unittest.cc b/components/metrics/structured/structured_metrics_recorder_unittest.cc index e872504c..c9aca85 100644 --- a/components/metrics/structured/structured_metrics_recorder_unittest.cc +++ b/components/metrics/structured/structured_metrics_recorder_unittest.cc
@@ -9,6 +9,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/strings/string_number_conversions.h" +#include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -18,7 +19,6 @@ #include "components/metrics/structured/storage.pb.h" #include "components/metrics/structured/structured_events.h" #include "components/metrics/structured/structured_metrics_features.h" -#include "components/metrics/structured/test/test_key_data_provider.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" @@ -137,9 +137,11 @@ class TestStructuredMetricsRecorder : public StructuredMetricsRecorder { public: - explicit TestStructuredMetricsRecorder( + TestStructuredMetricsRecorder( + const base::FilePath& device_key_path, raw_ptr<metrics::MetricsProvider> system_profile_provider) - : StructuredMetricsRecorder(/*write_delay=*/base::Seconds(0), + : StructuredMetricsRecorder(device_key_path, + /*write_delay=*/base::Seconds(0), system_profile_provider) {} using StructuredMetricsRecorder::StructuredMetricsRecorder; @@ -151,13 +153,6 @@ protected: void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - // Fixed paths to store keys for test. - device_key_path_ = - temp_dir_.GetPath().Append("structured_metrics").Append("device_keys"); - profile_key_path_ = - temp_dir_.GetPath().Append("structured_metrics").Append("keys"); - Recorder::GetInstance()->SetUiTaskRunner( task_environment_.GetMainThreadTaskRunner()); StructuredMetricsClient::Get()->SetDelegate(&test_recorder_); @@ -168,9 +163,15 @@ base::FilePath TempDirPath() { return temp_dir_.GetPath(); } - base::FilePath ProfileKeyFilePath() { return profile_key_path_; } + base::FilePath ProfileKeyFilePath() { + return temp_dir_.GetPath().Append("structured_metrics").Append("keys"); + } - base::FilePath DeviceKeyFilePath() { return device_key_path_; } + base::FilePath DeviceKeyFilePath() { + return temp_dir_.GetPath() + .Append("structured_metrics") + .Append("device_keys"); + } void TearDown() override { StructuredMetricsClient::Get()->UnsetDelegate(); } @@ -243,9 +244,7 @@ system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); // Create the provider, normally done by the ChromeMetricsServiceClient. recorder_ = std::make_unique<TestStructuredMetricsRecorder>( - system_profile_provider_.get()); - recorder_->InitializeKeyDataProvider(std::make_unique<TestKeyDataProvider>( - device_key_path_, profile_key_path_)); + DeviceKeyFilePath(), system_profile_provider_.get()); // Enable recording, normally done after the metrics service has checked // consent allows recording. recorder_->EnableRecording(); @@ -261,25 +260,12 @@ system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); // Create the provider, normally done by the ChromeMetricsServiceClient. recorder_ = std::make_unique<TestStructuredMetricsRecorder>( - system_profile_provider_.get()); - recorder_->InitializeKeyDataProvider( - std::make_unique<TestKeyDataProvider>(device_key_path_)); + DeviceKeyFilePath(), system_profile_provider_.get()); // Enable recording, normally done after the metrics service has checked // consent allows recording. recorder_->EnableRecording(); } - // Sets up StructuredMetricsRecorder. - void InitWithoutEnabling() { - // Create a system profile, normally done by ChromeMetricsServiceClient. - system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); - // Create the provider, normally done by the ChromeMetricsServiceClient. - recorder_ = std::make_unique<TestStructuredMetricsRecorder>( - system_profile_provider_.get()); - recorder_->InitializeKeyDataProvider( - std::make_unique<TestKeyDataProvider>(device_key_path_)); - } - bool is_initialized() { return recorder_->init_state_ == StructuredMetricsRecorder::InitState::kInitialized; @@ -350,9 +336,6 @@ private: TestRecorder test_recorder_; - - base::FilePath device_key_path_; - base::FilePath profile_key_path_; }; // Simple test to ensure initialization works correctly in the case of a @@ -429,7 +412,9 @@ // initialization still completes correctly, but recording is correctly set to // disabled. TEST_F(StructuredMetricsRecorderTest, RecordingDisabledDuringInitialization) { - InitWithoutEnabling(); + system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); + recorder_ = std::make_unique<TestStructuredMetricsRecorder>( + system_profile_provider_.get()); OnProfileAdded(TempDirPath()); OnRecordingDisabled(); @@ -446,7 +431,9 @@ // Ensure that recording is disabled until explicitly enabled with a call to // OnRecordingEnabled. TEST_F(StructuredMetricsRecorderTest, RecordingDisabledByDefault) { - InitWithoutEnabling(); + system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); + recorder_ = std::make_unique<TestStructuredMetricsRecorder>( + system_profile_provider_.get()); OnProfileAdded(TempDirPath()); Wait(); @@ -871,7 +858,10 @@ ASSERT_TRUE( base::WriteFile(events_dir.Append("event"), proto.SerializeAsString())); - Init(); + system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); + recorder_ = std::make_unique<TestStructuredMetricsRecorder>( + system_profile_provider_.get()); + OnProfileAdded(TempDirPath()); SetExternalMetricsDirForTest(events_dir); OnRecordingEnabled(); task_environment_.AdvanceClock(base::Hours(10)); @@ -889,7 +879,9 @@ base::WriteFile(events_dir.Append("event"), proto.SerializeAsString())); system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); - Init(); + recorder_ = std::make_unique<TestStructuredMetricsRecorder>( + system_profile_provider_.get()); + OnProfileAdded(TempDirPath()); SetExternalMetricsDirForTest(events_dir); OnRecordingDisabled(); task_environment_.AdvanceClock(base::Hours(10)); @@ -923,7 +915,6 @@ events::v2::test_project_one::TestEventOne().SetTestMetricTwo(1).Record(); OnProfileAdded(TempDirPath()); - // Called before user key is loaded. events::v2::test_project_one::TestEventOne().SetTestMetricTwo(1).Record(); Wait(); @@ -977,8 +968,9 @@ // completes returns no events. TEST_F(StructuredMetricsRecorderTest, ReportsNothingBeforeInitializationComplete) { - InitWithoutEnabling(); - + system_profile_provider_ = std::make_unique<TestSystemProfileProvider>(); + recorder_ = std::make_unique<TestStructuredMetricsRecorder>( + system_profile_provider_.get()); EXPECT_EQ(GetUMAEventMetrics().events_size(), 0); EXPECT_EQ(GetEventMetrics().events_size(), 0); OnRecordingEnabled();
diff --git a/components/metrics/structured/structured_metrics_service_unittest.cc b/components/metrics/structured/structured_metrics_service_unittest.cc index 073e4be..529af7d9 100644 --- a/components/metrics/structured/structured_metrics_service_unittest.cc +++ b/components/metrics/structured/structured_metrics_service_unittest.cc
@@ -18,7 +18,6 @@ #include "components/metrics/structured/structured_metrics_features.h" #include "components/metrics/structured/structured_metrics_prefs.h" #include "components/metrics/structured/structured_metrics_recorder.h" -#include "components/metrics/structured/test/test_key_data_provider.h" #include "components/metrics/test/test_metrics_service_client.h" #include "components/metrics/unsent_log_store.h" #include "components/metrics/unsent_log_store_metrics_impl.h" @@ -92,10 +91,8 @@ void Init() { auto recorder = std::unique_ptr<StructuredMetricsRecorder>( - new StructuredMetricsRecorder(base::Seconds(0), + new StructuredMetricsRecorder(DeviceKeyFilePath(), base::Seconds(0), system_profile_provider_.get())); - recorder->InitializeKeyDataProvider(std::make_unique<TestKeyDataProvider>( - DeviceKeyFilePath(), ProfileKeyFilePath())); recorder->OnProfileAdded(temp_dir_.GetPath()); service_ = std::unique_ptr<StructuredMetricsService>( new StructuredMetricsService(&client_, &prefs_, std::move(recorder)));
diff --git a/components/metrics/structured/test/test_key_data_provider.cc b/components/metrics/structured/test/test_key_data_provider.cc deleted file mode 100644 index d14b573..0000000 --- a/components/metrics/structured/test/test_key_data_provider.cc +++ /dev/null
@@ -1,68 +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. - -#include "components/metrics/structured/test/test_key_data_provider.h" - -namespace metrics::structured { - -TestKeyDataProvider::TestKeyDataProvider(const base::FilePath& device_key_path) - : device_key_path_(device_key_path), profile_key_path_(base::FilePath()) {} -TestKeyDataProvider::TestKeyDataProvider(const base::FilePath& device_key_path, - const base::FilePath& profile_key_path) - : device_key_path_(device_key_path), profile_key_path_(profile_key_path) {} - -TestKeyDataProvider::~TestKeyDataProvider() = default; - -KeyData* TestKeyDataProvider::GetDeviceKeyData() { - DCHECK(HasDeviceKey()); - - return device_key_data_.get(); -} - -KeyData* TestKeyDataProvider::GetProfileKeyData() { - DCHECK(HasProfileKey()); - - return profile_key_data_.get(); -} - -bool TestKeyDataProvider::HasProfileKey() { - return profile_key_data_ != nullptr; -} - -bool TestKeyDataProvider::HasDeviceKey() { - return device_key_data_ != nullptr; -} - -void TestKeyDataProvider::InitializeDeviceKey(base::OnceClosure callback) { - DCHECK(!device_key_path_.empty()); - - device_key_data_ = std::make_unique<KeyData>( - device_key_path_, base::Milliseconds(0), std::move(callback)); -} - -void TestKeyDataProvider::InitializeProfileKey( - const base::FilePath& profile_path, - base::OnceClosure callback) { - // If the profile path has not been set, then set it here. - if (profile_key_path_.empty()) { - profile_key_path_ = profile_path; - } - - DCHECK(!profile_key_path_.empty()); - - profile_key_data_ = std::make_unique<KeyData>( - profile_key_path_, base::Milliseconds(0), std::move(callback)); -} - -void TestKeyDataProvider::Purge() { - if (HasProfileKey()) { - GetProfileKeyData()->Purge(); - } - - if (HasDeviceKey()) { - GetDeviceKeyData()->Purge(); - } -} - -} // namespace metrics::structured
diff --git a/components/metrics/structured/test/test_key_data_provider.h b/components/metrics/structured/test/test_key_data_provider.h deleted file mode 100644 index ba5ae0ad..0000000 --- a/components/metrics/structured/test/test_key_data_provider.h +++ /dev/null
@@ -1,49 +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. - -#ifndef COMPONENTS_METRICS_STRUCTURED_TEST_TEST_KEY_DATA_PROVIDER_H_ -#define COMPONENTS_METRICS_STRUCTURED_TEST_TEST_KEY_DATA_PROVIDER_H_ - -#include <memory> - -#include "base/files/file_path.h" -#include "components/metrics/structured/key_data_provider.h" - -namespace metrics::structured { - -// Test implementation for KeyDataProvider. -// -// If only the |device_key_path| is provided in the ctor, then -// |profile_key_data_| will be empty until InitializeProfileKey is called and -// created in specified path |profile_path|. If |profile_key_path| is provided -// in the ctor, then |profile_path| provided in InitializeProfileKey will be -// ignored. -class TestKeyDataProvider : public KeyDataProvider { - public: - explicit TestKeyDataProvider(const base::FilePath& device_key_path); - TestKeyDataProvider(const base::FilePath& device_key_path, - const base::FilePath& profile_key_path); - ~TestKeyDataProvider() override; - - // KeyDataProvider: - KeyData* GetDeviceKeyData() override; - KeyData* GetProfileKeyData() override; - bool HasProfileKey() override; - bool HasDeviceKey() override; - void InitializeDeviceKey(base::OnceClosure callback) override; - void InitializeProfileKey(const base::FilePath& profile_path, - base::OnceClosure callback) override; - void Purge() override; - - private: - base::FilePath device_key_path_; - base::FilePath profile_key_path_; - - std::unique_ptr<KeyData> device_key_data_; - std::unique_ptr<KeyData> profile_key_data_; -}; - -} // namespace metrics::structured - -#endif // COMPONENTS_METRICS_STRUCTURED_TEST_TEST_KEY_DATA_PROVIDER_H_
diff --git a/components/metrics/structured/test/test_structured_metrics_provider.cc b/components/metrics/structured/test/test_structured_metrics_provider.cc index 6619b8e..7d0dee2b 100644 --- a/components/metrics/structured/test/test_structured_metrics_provider.cc +++ b/components/metrics/structured/test/test_structured_metrics_provider.cc
@@ -5,9 +5,9 @@ #include "components/metrics/structured/test/test_structured_metrics_provider.h" #include "base/files/file_path.h" -#include "base/run_loop.h" +#include "base/logging.h" #include "base/test/bind.h" -#include "components/metrics/structured/test/test_key_data_provider.h" +#include "testing/gtest/include/gtest/gtest.h" namespace metrics::structured { @@ -16,16 +16,13 @@ system_profile_provider_ = std::make_unique<MetricsProvider>(); structured_metrics_recorder_ = std::unique_ptr<StructuredMetricsRecorder>( new StructuredMetricsRecorder( - /*write_delay=*/base::Seconds(0), system_profile_provider_.get())); - structured_metrics_recorder_->InitializeKeyDataProvider( - std::make_unique<TestKeyDataProvider>( temp_dir_.GetPath() .Append(FILE_PATH_LITERAL("structured_metrics")) - .Append(FILE_PATH_LITERAL("device_keys")))); + .Append(FILE_PATH_LITERAL("device_keys")), + base::Seconds(0), system_profile_provider_.get())); structured_metrics_provider_ = std::unique_ptr<StructuredMetricsProvider>( - new StructuredMetricsProvider( - /*write_delay=*/base::Seconds(0), - structured_metrics_recorder_.get())); + new StructuredMetricsProvider(base::Seconds(0), + structured_metrics_recorder_.get())); Recorder::GetInstance()->AddObserver(this); } } @@ -49,12 +46,7 @@ absl::optional<const StructuredEventProto*> TestStructuredMetricsProvider::FindEvent(uint64_t project_name_hash, uint64_t event_name_hash) { - if (!structured_metrics_provider_->recorder().can_provide_metrics()) { - return absl::nullopt; - } - const EventsProto& events = TestStructuredMetricsProvider::ReadEvents(); - for (const auto& event : events.non_uma_events()) { if (event.project_name_hash() == project_name_hash && event.event_name_hash() == event_name_hash) { @@ -68,10 +60,6 @@ TestStructuredMetricsProvider::FindEvents(uint64_t project_name_hash, uint64_t event_name_hash) { std::vector<const StructuredEventProto*> events_vector; - if (!structured_metrics_provider_->recorder().can_provide_metrics()) { - return events_vector; - } - const EventsProto& events = TestStructuredMetricsProvider::ReadEvents(); for (const auto& event : events.non_uma_events()) { if (event.project_name_hash() == project_name_hash && @@ -111,16 +99,4 @@ project_name_hash); } -void TestStructuredMetricsProvider::AddProfilePath( - const base::FilePath& user_path) { - OnProfileAdded(temp_dir_.GetPath().Append(user_path)); -} - -void TestStructuredMetricsProvider::WaitUntilReady() { - base::RunLoop run_loop; - structured_metrics_provider_->recorder().SetOnReadyToRecord( - base::BindLambdaForTesting([&run_loop]() { run_loop.Quit(); })); - run_loop.Run(); -} - } // namespace metrics::structured
diff --git a/components/metrics/structured/test/test_structured_metrics_provider.h b/components/metrics/structured/test/test_structured_metrics_provider.h index f17d908..a5bb3c2 100644 --- a/components/metrics/structured/test/test_structured_metrics_provider.h +++ b/components/metrics/structured/test/test_structured_metrics_provider.h
@@ -44,11 +44,6 @@ void EnableRecording(); void DisableRecording(); - void AddProfilePath(const base::FilePath& user_path); - - // Waits until the recorder is fully initialized. - void WaitUntilReady(); - // Sets a callback that will be called after the event is flushed to // persistence. void SetOnEventsRecordClosure(
diff --git a/components/password_manager/ios/password_manager_java_script_feature.mm b/components/password_manager/ios/password_manager_java_script_feature.mm index 0d14d44..9207fc4 100644 --- a/components/password_manager/ios/password_manager_java_script_feature.mm +++ b/components/password_manager/ios/password_manager_java_script_feature.mm
@@ -90,7 +90,9 @@ PasswordManagerJavaScriptFeature::PasswordManagerJavaScriptFeature() : web::JavaScriptFeature( - web::ContentWorld::kIsolatedWorld, + // TODO(crbug.com/1175793): Move autofill code to kIsolatedWorld + // once all scripts are converted to JavaScriptFeatures. + web::ContentWorld::kPageContentWorld, {FeatureScript::CreateWithFilename( kScriptName, FeatureScript::InjectionTime::kDocumentStart,
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index aaf9d397f..8e89ebf 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -1759,19 +1759,6 @@ if (page_index == page_count_ - 1) { UnserializeNodes(); -#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) - if (features::IsPdfOcrEnabled() && !did_get_a_text_run_ && has_image) { - base::UmaHistogramBoolean( - "Accessibility.PdfOcr.ActiveWhenInaccessiblePdfOpened", - ocr_service_ != nullptr); - - if (ocr_service_) { - // Record the number of pages in PDF opened for PDF OCR. - base::UmaHistogramCounts1000( - "Accessibility.PdfOcr.InaccessiblePdfPageCount", page_count_); - } - } -#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) } } @@ -1844,14 +1831,29 @@ render_accessibility->SetPluginTreeSource(this); nodes_.clear(); - if (!did_unserialize_nodes_once_) { + if (!sent_metrics_once_) { // If the user turns on PDF OCR after opening a PDF, its PDF a11y tree gets - // created again. `did_unserialize_nodes_once_` helps to determine whether + // created again. `sent_metrics_once_` helps to determine whether // it's first time to create a PDF a11y tree. When a PDF is opened, the UMA - // metric, "Accessibility.PDF.HasAccessibleText", needs be recorded once. - did_unserialize_nodes_once_ = true; + // metrics need be recorded once. + sent_metrics_once_ = true; + base::UmaHistogramBoolean("Accessibility.PDF.HasAccessibleText", did_get_a_text_run_); + if (!did_get_a_text_run_) { + base::UmaHistogramCounts1000( + "Accessibility.PdfOcr.InaccessiblePdfPageCount", page_count_); + } + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + // TODO(crbug.com/1474770): Update this and other cases with a + // `IsAccessiblePDF` function. + if (features::IsPdfOcrEnabled() && !did_get_a_text_run_) { + base::UmaHistogramBoolean( + "Accessibility.PdfOcr.ActiveWhenInaccessiblePdfOpened", + ocr_service_ != nullptr); + } +#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) } }
diff --git a/components/pdf/renderer/pdf_accessibility_tree.h b/components/pdf/renderer/pdf_accessibility_tree.h index 3cd082d..52f2f723 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.h +++ b/components/pdf/renderer/pdf_accessibility_tree.h
@@ -373,7 +373,7 @@ uint32_t next_page_index_ = 0; bool did_get_a_text_run_ = false; - bool did_unserialize_nodes_once_ = false; + bool sent_metrics_once_ = false; #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) // The postamble page is added to the accessibility tree to inform the user
diff --git a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc index b31d6d03..d2ea6507 100644 --- a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc +++ b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
@@ -2466,6 +2466,24 @@ /*expected_count=*/page_count * 2); histograms.ExpectTotalCount("Accessibility.PdfOcr.PDFImages", /*expected_count=*/page_count * 4); + + // TODO(crbug.com/1443346): The current test fixture does not trigger + // `PdfAccessibilityTree::MaybeHandleAccessibilityChange` when OCR is enabled + // after tree load, and hence does result in calling + // `PdfAccessibilityTree::SetAccessibilityPageInfo` for the second time. + // Either update text fixture to be more realistic, or add metrics test to + // browser test without fake OCR service. + histograms.ExpectBucketCount("Accessibility.PDF.HasAccessibleText", + /*sample=*/false, + /*expected_count=*/1); + histograms.ExpectTotalCount("Accessibility.PDF.HasAccessibleText", + /*expected_count=*/1); + + histograms.ExpectBucketCount("Accessibility.PdfOcr.InaccessiblePdfPageCount", + doc_info_.page_count, + /*expected_count=*/1); + histograms.ExpectTotalCount("Accessibility.PdfOcr.InaccessiblePdfPageCount", + /*expected_count=*/1); } TEST_P(PdfOcrServiceTest, EmptyOCRResults) {
diff --git a/components/reading_list/core/reading_list_model_storage_impl.cc b/components/reading_list/core/reading_list_model_storage_impl.cc index f0a7877..2e58190 100644 --- a/components/reading_list/core/reading_list_model_storage_impl.cc +++ b/components/reading_list/core/reading_list_model_storage_impl.cc
@@ -10,6 +10,7 @@ #include "base/functional/bind.h" #include "base/memory/scoped_refptr.h" #include "base/time/clock.h" +#include "base/trace_event/trace_event.h" #include "components/reading_list/core/proto/reading_list.pb.h" #include "components/sync/model/metadata_batch.h" #include "url/gurl.h" @@ -142,6 +143,7 @@ ReadingListEntries loaded_entries, const absl::optional<syncer::ModelError>& error, std::unique_ptr<syncer::MetadataBatch> metadata_batch) { + TRACE_EVENT0("ui", "ReadingListModelStorageImpl::OnReadAllMetadata"); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (error) { std::move(load_callback_).Run(base::unexpected(error->message()));
diff --git a/components/reading_list/core/reading_list_sync_bridge.cc b/components/reading_list/core/reading_list_sync_bridge.cc index c25371b..55bb50f 100644 --- a/components/reading_list/core/reading_list_sync_bridge.cc +++ b/components/reading_list/core/reading_list_sync_bridge.cc
@@ -11,6 +11,7 @@ #include "base/functional/bind.h" #include "base/memory/scoped_refptr.h" #include "base/time/clock.h" +#include "base/trace_event/trace_event.h" #include "components/reading_list/core/reading_list_model_impl.h" #include "components/sync/base/data_type_histogram.h" #include "components/sync/model/entity_change.h" @@ -41,6 +42,7 @@ void ReadingListSyncBridge::ModelReadyToSync( ReadingListModelImpl* model, std::unique_ptr<syncer::MetadataBatch> sync_metadata_batch) { + TRACE_EVENT0("ui", "ReadingListSyncBridge::ModelReadyToSync"); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(model); DCHECK(!model_);
diff --git a/components/reporting/proto/BUILD.gn b/components/reporting/proto/BUILD.gn index cadfc38..df32926 100644 --- a/components/reporting/proto/BUILD.gn +++ b/components/reporting/proto/BUILD.gn
@@ -103,3 +103,11 @@ deps = [ ":status_proto" ] } + +proto_library("configuration_file_proto") { + proto_in_dir = "//" + + sources = [ "synced/configuration_file.proto" ] + + deps = [ ":record_constants" ] +}
diff --git a/components/reporting/proto/synced/configuration_file.proto b/components/reporting/proto/synced/configuration_file.proto new file mode 100644 index 0000000..c4fc46c --- /dev/null +++ b/components/reporting/proto/synced/configuration_file.proto
@@ -0,0 +1,32 @@ +// 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. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package reporting; + +import "components/reporting/proto/synced/record_constants.proto"; + +// Proto returned from the reporting server if requested by the client, this +// proto tells the client if any destinations should be blocked at the moment. +message ConfigFile { + // Blocked destinations. + repeated EventConfig event_configs = 1; + // Verified by the client to make sure that the response wasn't altered. + optional bytes config_file_signature = 2; +} + +// Control by destination. +message EventConfig { + optional Destination destination = 1; + // Minimum version where a destination should be blocked. + // Inclusive. [minimum_release_version, current or maximum_release_version] + // If these fields are not included the destination will be blocked on + // all versions. + optional int32 minimum_release_version = 2; + // Maximum version where a destination should be blocked. See above. + optional int32 maximum_release_version = 3; +}
diff --git a/components/sync/engine/commit_contribution_impl.cc b/components/sync/engine/commit_contribution_impl.cc index 602a1ed..4f8a6d4 100644 --- a/components/sync/engine/commit_contribution_impl.cc +++ b/components/sync/engine/commit_contribution_impl.cc
@@ -283,9 +283,9 @@ } } - if (commit_proto->specifics().has_password()) { - EncryptPasswordSpecificsData(commit_proto); - } else if (cryptographer_) { + // Passwords have different encryption scheme, see ModelTypeWorker. + // TODO(crbug.com/1468523): migrate encryption to ModelTypeWorker. + if (cryptographer_ && !commit_proto->specifics().has_password()) { if (commit_proto->has_specifics()) { sync_pb::EntitySpecifics encrypted_specifics; bool result = cryptographer_->Encrypt( @@ -308,40 +308,4 @@ AddDefaultFieldValue(type_, commit_proto->mutable_specifics()); } -void CommitContributionImpl::EncryptPasswordSpecificsData( - sync_pb::SyncEntity* commit_proto) { - DCHECK(cryptographer_); - const sync_pb::PasswordSpecifics& password_specifics = - commit_proto->specifics().password(); - const sync_pb::PasswordSpecificsData& password_data = - password_specifics.client_only_encrypted_data(); - sync_pb::EntitySpecifics encrypted_password; - - // Keep the unencrypted metadata for non-custom passphrase users. - if (!IsExplicitPassphrase(passphrase_type_)) { - *encrypted_password.mutable_password()->mutable_unencrypted_metadata() = - commit_proto->specifics().password().unencrypted_metadata(); - } - - bool result = cryptographer_->Encrypt( - password_data, - encrypted_password.mutable_password()->mutable_encrypted()); - DCHECK(result); - if (base::FeatureList::IsEnabled(syncer::kPasswordNotesWithBackup)) { - // `encrypted_notes_backup` field needs to be populated regardless of - // whether or not there are any notes. - result = cryptographer_->Encrypt(password_data.notes(), - encrypted_password.mutable_password() - ->mutable_encrypted_notes_backup()); - DCHECK(result); - // When encrypting both blobs succeeds, both encrypted blobs must use the - // key name. - DCHECK_EQ( - encrypted_password.password().encrypted().key_name(), - encrypted_password.password().encrypted_notes_backup().key_name()); - } - *commit_proto->mutable_specifics() = std::move(encrypted_password); - commit_proto->set_name("encrypted"); -} - } // namespace syncer
diff --git a/components/sync/engine/commit_contribution_impl.h b/components/sync/engine/commit_contribution_impl.h index 6f7af815..cc1dee65 100644 --- a/components/sync/engine/commit_contribution_impl.h +++ b/components/sync/engine/commit_contribution_impl.h
@@ -73,9 +73,6 @@ // Generates id for new entities and encrypts entity if needed. void AdjustCommitProto(sync_pb::SyncEntity* commit_proto); - // Encrypt the specifics and hide the title if necessary. - void EncryptPasswordSpecificsData(sync_pb::SyncEntity* commit_proto); - const ModelType type_; // A callback to inform the object that created this contribution about commit
diff --git a/components/sync/engine/commit_contribution_impl_unittest.cc b/components/sync/engine/commit_contribution_impl_unittest.cc index 7b2f6e4..c5d7ded6 100644 --- a/components/sync/engine/commit_contribution_impl_unittest.cc +++ b/components/sync/engine/commit_contribution_impl_unittest.cc
@@ -239,140 +239,6 @@ EXPECT_TRUE(entity.unique_position().has_custom_compressed_v1()); } -// Verifies how PASSWORDS protos are committed on the wire, making sure the data -// is properly encrypted except for password metadata. -TEST(CommitContributionImplTest, - PopulateCommitProtoPasswordWithoutCustomPassphrase) { - const std::string kSignonRealm = "signon_realm"; - const int64_t kBaseVersion = 7; - const int kDummyTimestamp = 123; - - auto data = std::make_unique<syncer::EntityData>(); - data->client_tag_hash = kTag; - sync_pb::PasswordSpecificsData* password_data = - data->specifics.mutable_password()->mutable_client_only_encrypted_data(); - password_data->set_signon_realm(kSignonRealm); - password_data->set_date_last_used(kDummyTimestamp); - - data->specifics.mutable_password()->mutable_unencrypted_metadata()->set_url( - kSignonRealm); - data->specifics.mutable_password() - ->mutable_unencrypted_metadata() - ->set_blacklisted(false); - data->specifics.mutable_password() - ->mutable_unencrypted_metadata() - ->set_date_last_used_windows_epoch_micros(kDummyTimestamp); - - auto request_data = std::make_unique<CommitRequestData>(); - request_data->sequence_number = 2; - request_data->base_version = kBaseVersion; - base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()), - &request_data->specifics_hash); - request_data->entity = std::move(data); - - std::unique_ptr<FakeCryptographer> cryptographer = - FakeCryptographer::FromSingleDefaultKey("dummy"); - - CommitRequestDataList requests_data; - requests_data.push_back(std::move(request_data)); - CommitContributionImpl contribution( - PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data), - /*on_commit_response_callback=*/base::NullCallback(), - /*on_full_commit_failure_callback=*/base::NullCallback(), - cryptographer.get(), PassphraseType::kImplicitPassphrase, - /*only_commit_specifics=*/false); - - sync_pb::ClientToServerMessage msg; - contribution.AddToCommitMessage(&msg); - - ASSERT_EQ(1, msg.commit().entries().size()); - SyncEntity entity = msg.commit().entries(0); - - // Exhaustively verify the populated SyncEntity. - EXPECT_TRUE(entity.id_string().empty()); - EXPECT_EQ(7, entity.version()); - EXPECT_EQ("encrypted", entity.name()); - EXPECT_EQ(kTag.value(), entity.client_tag_hash()); - EXPECT_FALSE(entity.deleted()); - EXPECT_FALSE(entity.specifics().has_encrypted()); - EXPECT_TRUE(entity.specifics().has_password()); - EXPECT_EQ(kSignonRealm, - entity.specifics().password().unencrypted_metadata().url()); - EXPECT_TRUE( - entity.specifics().password().unencrypted_metadata().has_blacklisted()); - EXPECT_FALSE( - entity.specifics().password().unencrypted_metadata().blacklisted()); - EXPECT_EQ(kDummyTimestamp, entity.specifics() - .password() - .unencrypted_metadata() - .date_last_used_windows_epoch_micros()); - EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty()); - EXPECT_TRUE(entity.parent_id_string().empty()); - EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1()); -} - -// Same as above but uses CUSTOM_PASSPHRASE. In this case, field -// |unencrypted_metadata| should be cleared. -TEST(CommitContributionImplTest, - PopulateCommitProtoPasswordWithCustomPassphrase) { - const std::string kSignonRealm = "signon_realm"; - const int kDummyTimestamp = 123; - const int64_t kBaseVersion = 7; - - auto data = std::make_unique<syncer::EntityData>(); - data->client_tag_hash = kTag; - sync_pb::PasswordSpecificsData* password_data = - data->specifics.mutable_password()->mutable_client_only_encrypted_data(); - password_data->set_signon_realm(kSignonRealm); - - data->specifics.mutable_password()->mutable_unencrypted_metadata()->set_url( - kSignonRealm); - data->specifics.mutable_password() - ->mutable_unencrypted_metadata() - ->set_blacklisted(false); - data->specifics.mutable_password() - ->mutable_unencrypted_metadata() - ->set_date_last_used_windows_epoch_micros(kDummyTimestamp); - - auto request_data = std::make_unique<CommitRequestData>(); - request_data->sequence_number = 2; - request_data->base_version = kBaseVersion; - base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()), - &request_data->specifics_hash); - request_data->entity = std::move(data); - - std::unique_ptr<FakeCryptographer> cryptographer = - FakeCryptographer::FromSingleDefaultKey("dummy"); - - CommitRequestDataList requests_data; - requests_data.push_back(std::move(request_data)); - CommitContributionImpl contribution( - PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data), - /*on_commit_response_callback=*/base::NullCallback(), - /*on_full_commit_failure_callback=*/base::NullCallback(), - cryptographer.get(), PassphraseType::kCustomPassphrase, - /*only_commit_specifics=*/false); - - sync_pb::ClientToServerMessage msg; - contribution.AddToCommitMessage(&msg); - - ASSERT_EQ(1, msg.commit().entries().size()); - SyncEntity entity = msg.commit().entries(0); - - // Exhaustively verify the populated SyncEntity. - EXPECT_TRUE(entity.id_string().empty()); - EXPECT_EQ(7, entity.version()); - EXPECT_EQ("encrypted", entity.name()); - EXPECT_EQ(kTag.value(), entity.client_tag_hash()); - EXPECT_FALSE(entity.deleted()); - EXPECT_FALSE(entity.specifics().has_encrypted()); - EXPECT_TRUE(entity.specifics().has_password()); - EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty()); - EXPECT_FALSE(entity.specifics().password().has_unencrypted_metadata()); - EXPECT_TRUE(entity.parent_id_string().empty()); - EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1()); -} - TEST(CommitContributionImplTest, ShouldPropagateFailedItemsOnCommitResponse) { auto data = std::make_unique<syncer::EntityData>(); data->client_tag_hash = ClientTagHash::FromHashed("hash"); @@ -446,89 +312,6 @@ contribution.ProcessCommitFailure(SyncCommitError::kNetworkError); } -TEST(CommitContributionImplTest, ShouldPopulatePasswordNotesBackup) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(syncer::kPasswordNotesWithBackup); - - const std::string kNoteValue = "Note Value"; - auto data = std::make_unique<syncer::EntityData>(); - data->client_tag_hash = kTag; - sync_pb::PasswordSpecificsData* password_data = - data->specifics.mutable_password()->mutable_client_only_encrypted_data(); - sync_pb::PasswordSpecificsData_Notes_Note* note = - password_data->mutable_notes()->add_note(); - note->set_value(kNoteValue); - - auto request_data = std::make_unique<CommitRequestData>(); - base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()), - &request_data->specifics_hash); - request_data->entity = std::move(data); - - CommitRequestDataList requests_data; - requests_data.push_back(std::move(request_data)); - - std::unique_ptr<FakeCryptographer> cryptographer = - FakeCryptographer::FromSingleDefaultKey("dummy"); - CommitContributionImpl contribution( - PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data), - /*on_commit_response_callback=*/base::NullCallback(), - /*on_full_commit_failure_callback=*/base::NullCallback(), - cryptographer.get(), PassphraseType::kImplicitPassphrase, - /*only_commit_specifics=*/false); - - sync_pb::ClientToServerMessage msg; - contribution.AddToCommitMessage(&msg); - - ASSERT_EQ(1, msg.commit().entries().size()); - SyncEntity entity = msg.commit().entries(0); - ASSERT_TRUE(entity.specifics().has_password()); - - // Verify the contents of the encrypted notes backup blob. - sync_pb::PasswordSpecificsData_Notes decrypted_notes; - cryptographer->Decrypt(entity.specifics().password().encrypted_notes_backup(), - &decrypted_notes); - ASSERT_EQ(1, decrypted_notes.note_size()); - EXPECT_EQ(kNoteValue, decrypted_notes.note(0).value()); -} - -TEST(CommitContributionImplTest, - ShouldPopulatePasswordNotesBackupWhenNoLocalNotes) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(syncer::kPasswordNotesWithBackup); - - auto data = std::make_unique<syncer::EntityData>(); - data->client_tag_hash = kTag; - sync_pb::PasswordSpecificsData* password_data = - data->specifics.mutable_password()->mutable_client_only_encrypted_data(); - password_data->set_signon_realm("signon_realm"); - - auto request_data = std::make_unique<CommitRequestData>(); - base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()), - &request_data->specifics_hash); - request_data->entity = std::move(data); - - CommitRequestDataList requests_data; - requests_data.push_back(std::move(request_data)); - - std::unique_ptr<FakeCryptographer> cryptographer = - FakeCryptographer::FromSingleDefaultKey("dummy"); - CommitContributionImpl contribution( - PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data), - /*on_commit_response_callback=*/base::NullCallback(), - /*on_full_commit_failure_callback=*/base::NullCallback(), - cryptographer.get(), PassphraseType::kImplicitPassphrase, - /*only_commit_specifics=*/false); - - sync_pb::ClientToServerMessage msg; - contribution.AddToCommitMessage(&msg); - - ASSERT_EQ(1, msg.commit().entries().size()); - SyncEntity entity = msg.commit().entries(0); - ASSERT_TRUE(entity.specifics().has_password()); - EXPECT_FALSE( - entity.specifics().password().encrypted_notes_backup().blob().empty()); -} - } // namespace } // namespace syncer
diff --git a/components/sync/engine/model_type_worker.cc b/components/sync/engine/model_type_worker.cc index 20e791ef..2cadf6a 100644 --- a/components/sync/engine/model_type_worker.cc +++ b/components/sync/engine/model_type_worker.cc
@@ -780,6 +780,10 @@ DCHECK(!encryption_enabled_ || (model_type_state_.encryption_key_name() == cryptographer_->GetDefaultEncryptionKeyName())); + + if (type_ == PASSWORDS) { + EncryptPasswordSpecificsData(&response); + } return std::make_unique<CommitContributionImpl>( type_, model_type_state_.type_context(), std::move(response), base::BindOnce(&ModelTypeWorker::OnCommitResponse, @@ -1254,6 +1258,53 @@ } } +void ModelTypeWorker::EncryptPasswordSpecificsData( + CommitRequestDataList* request_data_list) { + CHECK(cryptographer_); + CHECK(encryption_enabled_); + + for (std::unique_ptr<CommitRequestData>& request_data : *request_data_list) { + EntityData* entity_data = request_data->entity.get(); + if (entity_data->is_deleted()) { + continue; + } + + const sync_pb::PasswordSpecifics& password_specifics = + entity_data->specifics.password(); + const sync_pb::PasswordSpecificsData& password_data = + password_specifics.client_only_encrypted_data(); + sync_pb::EntitySpecifics encrypted_password; + + // Keep the unencrypted metadata for non-custom passphrase users. + if (!IsExplicitPassphrase(passphrase_type_)) { + *encrypted_password.mutable_password()->mutable_unencrypted_metadata() = + password_specifics.unencrypted_metadata(); + } + + bool result = cryptographer_->Encrypt( + password_data, + encrypted_password.mutable_password()->mutable_encrypted()); + DCHECK(result); + if (base::FeatureList::IsEnabled(syncer::kPasswordNotesWithBackup)) { + // `encrypted_notes_backup` field needs to be populated regardless of + // whether or not there are any notes. + result = cryptographer_->Encrypt(password_data.notes(), + encrypted_password.mutable_password() + ->mutable_encrypted_notes_backup()); + DCHECK(result); + // When encrypting both blobs succeeds, both encrypted blobs must use the + // key name. + DCHECK_EQ( + encrypted_password.password().encrypted().key_name(), + encrypted_password.password().encrypted_notes_backup().key_name()); + } + // Replace the entire specifics, among other things to ensure that any + // client-only fields are cleared. + entity_data->specifics = std::move(encrypted_password); + entity_data->name = "encrypted"; + } +} + GetLocalChangesRequest::GetLocalChangesRequest( CancelationSignal* cancelation_signal) : cancelation_signal_(cancelation_signal),
diff --git a/components/sync/engine/model_type_worker.h b/components/sync/engine/model_type_worker.h index 008c09fa..9696210 100644 --- a/components/sync/engine/model_type_worker.h +++ b/components/sync/engine/model_type_worker.h
@@ -303,6 +303,9 @@ // Copies |pending_invalidations_| vector to |model_type_state_|. void UpdateModelTypeStateInvalidations(); + // Encrypt the specifics and hide the title if necessary. + void EncryptPasswordSpecificsData(CommitRequestDataList* request_data_list); + // The (up to kMaxPayloads) most recent invalidations received since the last // successful sync cycle. std::vector<PendingInvalidation> pending_invalidations_;
diff --git a/components/sync/engine/model_type_worker_unittest.cc b/components/sync/engine/model_type_worker_unittest.cc index c6bf3a5..1f5e8ba7 100644 --- a/components/sync/engine/model_type_worker_unittest.cc +++ b/components/sync/engine/model_type_worker_unittest.cc
@@ -228,6 +228,11 @@ worker_->ConnectSync(std::move(processor)); } + void NormalInitializeWithCustomPassphrase() { + NormalInitialize(); + worker_->UpdatePassphraseType(PassphraseType::kCustomPassphrase); + } + // Mimic a Nigori update with a keybag that cannot be decrypted, which means // the cryptographer becomes unusable (no default key until the issue gets // resolved, via DecryptPendingKey()). @@ -471,6 +476,7 @@ worker_.reset(); } + FakeCryptographer* cryptographer() { return &cryptographer_; } MockModelTypeProcessor* processor() { return mock_type_processor_; } ModelTypeWorker* worker() { return worker_.get(); } SingleTypeMockServer* server() { return mock_server_.get(); } @@ -2053,6 +2059,7 @@ sync_pb::PasswordSpecificsData* password_data = specifics.mutable_password()->mutable_client_only_encrypted_data(); password_data->set_signon_realm("signon_realm"); + specifics.mutable_password()->mutable_unencrypted_metadata()->set_url("url"); // Normal commit request stuff. processor()->SetCommitRequest(GenerateCommitRequest(kHash1, specifics)); @@ -2060,14 +2067,66 @@ ASSERT_EQ(1U, server()->GetNumCommitMessages()); EXPECT_EQ(1, server()->GetNthCommitMessage(0).commit().entries_size()); ASSERT_TRUE(server()->HasCommitEntity(kHash1)); - const SyncEntity& tag1_entity = server()->GetLastCommittedEntity(kHash1); + const SyncEntity& entity = server()->GetLastCommittedEntity(kHash1); - EXPECT_FALSE(tag1_entity.specifics().has_encrypted()); - EXPECT_TRUE(tag1_entity.specifics().has_password()); - EXPECT_TRUE(tag1_entity.specifics().password().has_encrypted()); + EXPECT_FALSE(entity.specifics().has_encrypted()); + EXPECT_TRUE(entity.specifics().has_password()); + EXPECT_TRUE(entity.specifics().password().has_encrypted()); + EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty()); // The title should be overwritten. - EXPECT_EQ(tag1_entity.name(), "encrypted"); + EXPECT_EQ(entity.name(), "encrypted"); + + // Exhaustively verify the populated SyncEntity. + EXPECT_EQ(entity.client_tag_hash(), kHash1.value()); + EXPECT_FALSE(entity.deleted()); + EXPECT_EQ(entity.specifics().password().unencrypted_metadata().url(), "url"); + EXPECT_TRUE(entity.parent_id_string().empty()); + EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1()); +} + +// Same as above but uses custom passphrase. In this case, field +// |unencrypted_metadata| should be cleared. +TEST_F(ModelTypeWorkerPasswordsTest, PasswordCommitWithCustomPassphrase) { + NormalInitializeWithCustomPassphrase(); + + EXPECT_EQ(0U, processor()->GetNumUpdateResponses()); + + // Init the Cryptographer, it'll cause the EKN to be pushed. + AddPendingKey(); + DecryptPendingKey(); + ASSERT_EQ(1U, processor()->GetNumUpdateResponses()); + EXPECT_EQ(default_encryption_key_name(), + processor()->GetNthUpdateState(0).encryption_key_name()); + + EntitySpecifics specifics; + sync_pb::PasswordSpecificsData* password_data = + specifics.mutable_password()->mutable_client_only_encrypted_data(); + password_data->set_signon_realm("signon_realm"); + specifics.mutable_password()->mutable_unencrypted_metadata()->set_url("url"); + + // Normal commit request stuff. + processor()->SetCommitRequest(GenerateCommitRequest(kHash1, specifics)); + DoSuccessfulCommit(); + ASSERT_EQ(1U, server()->GetNumCommitMessages()); + EXPECT_EQ(1, server()->GetNthCommitMessage(0).commit().entries_size()); + ASSERT_TRUE(server()->HasCommitEntity(kHash1)); + const SyncEntity& entity = server()->GetLastCommittedEntity(kHash1); + + EXPECT_FALSE(entity.specifics().has_encrypted()); + EXPECT_TRUE(entity.specifics().has_password()); + EXPECT_TRUE(entity.specifics().password().has_encrypted()); + EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty()); + + // The title should be overwritten. + EXPECT_EQ(entity.name(), "encrypted"); + + // Exhaustively verify the populated SyncEntity. + EXPECT_EQ(entity.client_tag_hash(), kHash1.value()); + EXPECT_FALSE(entity.deleted()); + EXPECT_FALSE(entity.specifics().password().has_unencrypted_metadata()); + EXPECT_TRUE(entity.parent_id_string().empty()); + EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1()); } // Similar to ReceiveDecryptableEntities but for PASSWORDS, which have a custom @@ -2705,6 +2764,67 @@ syncer::PasswordNotesStateForUMA::kSetOnlyInBackupButCorrupted, 1); } +TEST_F(ModelTypeWorkerPasswordsTestWithNotes, + ShouldPopulatePasswordNotesBackup) { + const std::string kPasswordInSpecificsNote = "Note Value"; + NormalInitialize(); + + // Create a new Nigori and allow the cryptographer to decrypt it. + AddPendingKey(); + DecryptPendingKey(); + + // Set a value for the note in the PasswordSpecificsData. + EntitySpecifics specifics; + sync_pb::PasswordSpecificsData* unencrypted_password = + specifics.mutable_password()->mutable_client_only_encrypted_data(); + unencrypted_password->set_password_value(kPassword); + unencrypted_password->mutable_notes()->add_note()->set_value( + kPasswordInSpecificsNote); + + // Normal commit request stuff. + processor()->SetCommitRequest(GenerateCommitRequest(kHash1, specifics)); + DoSuccessfulCommit(); + ASSERT_EQ(1U, server()->GetNumCommitMessages()); + EXPECT_EQ(1, server()->GetNthCommitMessage(0).commit().entries_size()); + ASSERT_TRUE(server()->HasCommitEntity(kHash1)); + const SyncEntity& entity = server()->GetLastCommittedEntity(kHash1); + + ASSERT_TRUE(entity.specifics().has_password()); + // Verify the contents of the encrypted notes backup blob. + sync_pb::PasswordSpecificsData_Notes decrypted_notes; + cryptographer()->Decrypt( + entity.specifics().password().encrypted_notes_backup(), &decrypted_notes); + ASSERT_EQ(1, decrypted_notes.note_size()); + EXPECT_EQ(kPasswordInSpecificsNote, decrypted_notes.note(0).value()); +} + +TEST_F(ModelTypeWorkerPasswordsTestWithNotes, + ShouldPopulatePasswordNotesBackupWhenNoLocalNotes) { + NormalInitialize(); + + // Create a new Nigori and allow the cryptographer to decrypt it. + AddPendingKey(); + DecryptPendingKey(); + + // Set a value for the note in the PasswordSpecificsData. + EntitySpecifics specifics; + sync_pb::PasswordSpecificsData* unencrypted_password = + specifics.mutable_password()->mutable_client_only_encrypted_data(); + unencrypted_password->set_password_value(kPassword); + + // Normal commit request stuff. + processor()->SetCommitRequest(GenerateCommitRequest(kHash1, specifics)); + DoSuccessfulCommit(); + ASSERT_EQ(1U, server()->GetNumCommitMessages()); + EXPECT_EQ(1, server()->GetNthCommitMessage(0).commit().entries_size()); + ASSERT_TRUE(server()->HasCommitEntity(kHash1)); + const SyncEntity& entity = server()->GetLastCommittedEntity(kHash1); + + ASSERT_TRUE(entity.specifics().has_password()); + EXPECT_FALSE( + entity.specifics().password().encrypted_notes_backup().blob().empty()); +} + // Verifies persisting invalidations load from the ModelTypeProcessor. TEST_F(ModelTypeWorkerTest, LoadInvalidations) { base::test::ScopedFeatureList feature;
diff --git a/components/test/data/autofill/credit_card_upload_form_address_and_cc.html b/components/test/data/autofill/credit_card_upload_form_address_and_cc.html index c37be50b..65b86a7b 100644 --- a/components/test/data/autofill/credit_card_upload_form_address_and_cc.html +++ b/components/test/data/autofill/credit_card_upload_form_address_and_cc.html
@@ -45,6 +45,7 @@ <button id="fill_invalid_cvc" type="button">Fill the CVC field with an invalid value</button> <button id="fill_card_only" type="button">Fill the credit card number and expiration fields only</button> <button id="fill_expired_expiration_date" type="button">Fill an expired expiration date</button> + <button id="fill_conflicting_name" type="button">Fill conflicting names</button> <button id="clear_cvc" type="button">Clear the CVC field</button> <button id="clear_name" type="button">Clear the name fields</button> <button id="clear_month" type="button">Clear the month field</button> @@ -114,6 +115,13 @@ document.getElementsByName("cc_year_exp")[0].value = "2000"; }); + document.getElementById("fill_conflicting_name").addEventListener( + "click", + function() { + document.getElementsByName("name_address")[0].value = "John Smith"; + document.getElementsByName("name_cc")[0].value = "Moe Szyslak"; + }); + document.getElementById("clear_cvc").addEventListener( "click", function() {
diff --git a/components/test/data/autofill/credit_card_upload_form_shipping_address.html b/components/test/data/autofill/credit_card_upload_form_shipping_address.html deleted file mode 100644 index 5adb40a8e..0000000 --- a/components/test/data/autofill/credit_card_upload_form_shipping_address.html +++ /dev/null
@@ -1,61 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> -<!-- -Copyright 2017 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<html> -<head> -<title>Credit Card Upload Test - Form with shipping address, leads to credit card form</title> -<meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> -</head> -<body> - <form id="checkout" name="checkout" action="/credit_card_upload_form_address_and_cc.html" method="post"> - <div>Name: <input type="text" name="name_address" autocomplete="name"></div> - <div>Address: <input type="text" name="address" autocomplete="address-line1"></div> - <div>City: <input type="text" name="city" autocomplete="address-level2"></div> - <div>State: <input type="text" name="state" autocomplete="address-level1"></div> - <div>Zip: <input type="text" name="zip" autocomplete="postal-code"></div> - <div>Country: <input type="text" name="country" autocomplete="country-name"></div> - <hr> - <button id="fill_form" type="button">Fill entire form with default values</button> - <button id="conflicting_name" type="button">Fill a different name than the next form</button> - <button id="conflicting_street_address" type="button">Fill a different street address than the next form</button> - <button id="conflicting_postal_code" type="button">Fill a different postal code than the next form</button> - <button id="submit" type="submit">Submit</button> - </form> -<script type="text/javascript"> - document.getElementById("fill_form").addEventListener( - "click", - function() { - document.getElementsByName("name_address")[0].value = "John Smith"; - document.getElementsByName("address")[0].value = "123 Testing St."; - document.getElementsByName("city")[0].value = "Mountain View"; - document.getElementsByName("state")[0].value = "California"; - document.getElementsByName("zip")[0].value = "94043"; - document.getElementsByName("country")[0].value = "US"; - }); - - document.getElementById("conflicting_name").addEventListener( - "click", - function() { - document.getElementsByName("name_address")[0].value = "Chrome Guy"; - }); - - document.getElementById("conflicting_street_address").addEventListener( - "click", - function() { - document.getElementsByName("address")[0].value = "456 Chromium Ave."; - }); - - document.getElementById("conflicting_postal_code").addEventListener( - "click", - function() { - document.getElementsByName("address")[0].value = "456 Chromium Ave."; - document.getElementsByName("city")[0].value = "San Francisco"; - document.getElementsByName("zip")[0].value = "94105"; - }); -</script> -</body> -</html>
diff --git a/components/test/data/autofill/heuristics-json/accept-new-version.sh b/components/test/data/autofill/heuristics-json/accept-new-version.sh index 73ce4b34..31a1cbb 100755 --- a/components/test/data/autofill/heuristics-json/accept-new-version.sh +++ b/components/test/data/autofill/heuristics-json/accept-new-version.sh
@@ -8,7 +8,7 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -for FILE in "${SCRIPT_DIR}"/*.json; do +for FILE in "${SCRIPT_DIR}"/**/*.json; do if [[ -f "${FILE}.new" ]]; then mv "${FILE}.new" "${FILE}" fi
diff --git a/components/test/data/autofill/heuristics-json/show-diffs.sh b/components/test/data/autofill/heuristics-json/show-diffs.sh index 77ad630..3eae90d6 100755 --- a/components/test/data/autofill/heuristics-json/show-diffs.sh +++ b/components/test/data/autofill/heuristics-json/show-diffs.sh
@@ -7,7 +7,9 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -for FILE in "${SCRIPT_DIR}"/*.json; do +shopt -s globstar # Enable ** + +for FILE in "${SCRIPT_DIR}"/**/*.json; do if [[ -f "${FILE}.new" ]]; then echo "${FILE} has different results:" diff -U5 "${FILE}" "${FILE}.new"
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 06defb3..93dfa67f 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -1629,34 +1629,6 @@ } } -bool SkiaRenderer::NeedsFlipY(const DrawQuad* quad) const { - // TODO(crbug.com/1449764): remove this workaround when bottom left origin - // image is supported by graphite. - if (!skia_output_surface_->IsUsingGraphite()) { - return false; - } - switch (quad->material) { - case DrawQuad::Material::kTextureContent: - return TextureDrawQuad::MaterialCast(quad)->y_flipped; - case DrawQuad::Material::kAggregatedRenderPass: { - auto* render_pass_quad = AggregatedRenderPassDrawQuad::MaterialCast(quad); - auto bypass = - render_pass_bypass_quads_.find(render_pass_quad->render_pass_id); - if (bypass == render_pass_bypass_quads_.end()) { - return false; - } - const DrawQuad* bypass_quad = bypass->second; - if (RenderPassRemainsTransparent( - bypass_quad->shared_quad_state->blend_mode)) { - return false; - } - return NeedsFlipY(bypass_quad); - } - default: - return false; - } -} - SkiaRenderer::DrawQuadParams SkiaRenderer::CalculateDrawQuadParams( const gfx::AxisTransform2d& target_to_device, const absl::optional<gfx::Rect>& scissor_rect, @@ -1669,11 +1641,6 @@ GetSampling(quad), draw_region); params.content_device_transform.PostConcat(target_to_device); - if (NeedsFlipY(quad)) { - float height = quad->visible_rect.height(); - params.content_device_transform.Scale(1, -1); - params.content_device_transform.Translate(0, -height); - } params.content_device_transform.Flatten(); // Respect per-quad setting overrides as highest priority setting
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index afeb088b..cebd142a 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -151,8 +151,6 @@ DrawQuadParams* params, SkColor4f* color); - bool NeedsFlipY(const DrawQuad* quad) const; - // The returned DrawQuadParams can be modified by the DrawX calls that accept // params so that they can apply explicit data transforms before sending to // Skia in a consistent manner.
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index fbb2169..b550e30 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -613,9 +613,18 @@ /*is_yuv_plane=*/false, mipmap); SkColorInfo color_info(color_type, image_context->alpha_type(), image_context->color_space()); + static_assert(skgpu::Origin::kTopLeft == + static_cast<skgpu::Origin>( + GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin), + ""); + static_assert(skgpu::Origin::kBottomLeft == + static_cast<skgpu::Origin>( + GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin), + ""); + skgpu::Origin origin = static_cast<skgpu::Origin>(image_context->origin()); auto image = SkImages::PromiseTextureFrom( graphite_recorder_, gfx::SizeToSkISize(image_context->size()), - texture_info, color_info, skgpu::graphite::Volatile::kYes, + texture_info, color_info, origin, skgpu::graphite::Volatile::kYes, FulfillGraphite, CleanUp, ReleaseGraphite, fulfill); image_context->SetImage(std::move(image), {texture_info}); } else {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d95944d..f2061c2 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1133,6 +1133,8 @@ "interest_group/ad_auction_service_impl.h", "interest_group/ad_auction_url_loader_interceptor.cc", "interest_group/ad_auction_url_loader_interceptor.h", + "interest_group/additional_bids_util.cc", + "interest_group/additional_bids_util.h", "interest_group/auction_metrics_recorder.cc", "interest_group/auction_metrics_recorder.h", "interest_group/auction_nonce_manager.cc",
diff --git a/content/browser/browsing_data/clear_site_data_handler.cc b/content/browser/browsing_data/clear_site_data_handler.cc index d53f993c..bcee3aab 100644 --- a/content/browser/browsing_data/clear_site_data_handler.cc +++ b/content/browser/browsing_data/clear_site_data_handler.cc
@@ -364,10 +364,12 @@ const ClearSiteDataTypeSet clear_site_data_types, const std::set<std::string>& storage_buckets_to_remove, base::OnceClosure callback) { - ClearSiteData(browser_context_getter_, origin, clear_site_data_types, - storage_buckets_to_remove, true /*avoid_closing_connections*/, - cookie_partition_key_, storage_key_, - partitioned_state_allowed_only_, std::move(callback)); + ClearSiteData(browser_context_getter_, + /*storage_partition_config=*/absl::nullopt, origin, + clear_site_data_types, storage_buckets_to_remove, + /*avoid_closing_connections=*/true, cookie_partition_key_, + storage_key_, partitioned_state_allowed_only_, + std::move(callback)); } // static
diff --git a/content/browser/browsing_data/clear_site_data_utils.cc b/content/browser/browsing_data/clear_site_data_utils.cc index 6818c2e..8be13cb4 100644 --- a/content/browser/browsing_data/clear_site_data_utils.cc +++ b/content/browser/browsing_data/clear_site_data_utils.cc
@@ -15,6 +15,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/browsing_data_filter_builder.h" #include "content/public/browser/browsing_data_remover.h" +#include "content/public/browser/storage_partition_config.h" #include "content/public/browser/web_contents.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -33,15 +34,17 @@ public: SiteDataClearer( BrowserContext* browser_context, + const absl::optional<StoragePartitionConfig> storage_partition_config, const url::Origin& origin, const ClearSiteDataTypeSet clear_site_data_types, const std::set<std::string>& storage_buckets_to_remove, bool avoid_closing_connections, - const absl::optional<net::CookiePartitionKey>& cookie_partition_key, - const absl::optional<blink::StorageKey>& storage_key, + const absl::optional<net::CookiePartitionKey> cookie_partition_key, + const absl::optional<blink::StorageKey> storage_key, bool partitioned_state_allowed_only, base::OnceClosure callback) - : origin_(origin), + : storage_partition_config_(storage_partition_config), + origin_(origin), clear_site_data_types_(clear_site_data_types), storage_buckets_to_remove_(storage_buckets_to_remove), avoid_closing_connections_(avoid_closing_connections), @@ -90,6 +93,10 @@ cookie_partition_key_)); cookie_filter_builder->SetPartitionedStateAllowedOnly( partitioned_state_allowed_only_); + if (storage_partition_config_.has_value()) { + cookie_filter_builder->SetStoragePartitionConfig( + storage_partition_config_.value()); + } pending_task_count_++; uint64_t remove_mask = BrowsingDataRemover::DATA_TYPE_COOKIES; @@ -110,9 +117,8 @@ // For storage buckets, no mask is being passed per se. Therefore, when // the storage buckets are successfully removed, the `failed_data_types` // arg should be set to 0 to align with existing behaviour in this class. - // TODO(zelin): Pass down storage partition and replace nullopt. remover_->RemoveStorageBucketsAndReply( - absl::nullopt, + storage_partition_config_, storage_key_.value_or(blink::StorageKey::CreateFirstParty(origin_)), storage_buckets_to_remove_, base::BindOnce(&SiteDataClearer::OnBrowsingDataRemoverDone, @@ -138,6 +144,10 @@ BrowsingDataFilterBuilder::Mode::kDelete)); origin_filter_builder->AddOrigin(origin_); origin_filter_builder->SetStorageKey(storage_key_); + if (storage_partition_config_.has_value()) { + origin_filter_builder->SetStoragePartitionConfig( + storage_partition_config_.value()); + } pending_task_count_++; remover_->RemoveWithFilterAndReply( @@ -176,6 +186,7 @@ delete this; } + const absl::optional<StoragePartitionConfig> storage_partition_config_; const url::Origin origin_; const ClearSiteDataTypeSet clear_site_data_types_; const std::set<std::string> storage_buckets_to_remove_; @@ -195,12 +206,13 @@ void ClearSiteData( const base::RepeatingCallback<BrowserContext*()>& browser_context_getter, + const absl::optional<StoragePartitionConfig> storage_partition_config, const url::Origin& origin, const ClearSiteDataTypeSet clear_site_data_types, const std::set<std::string>& storage_buckets_to_remove, bool avoid_closing_connections, - const absl::optional<net::CookiePartitionKey>& cookie_partition_key, - const absl::optional<blink::StorageKey>& storage_key, + const absl::optional<net::CookiePartitionKey> cookie_partition_key, + const absl::optional<blink::StorageKey> storage_key, bool partitioned_state_allowed_only, base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -213,10 +225,11 @@ std::move(callback).Run(); return; } - (new SiteDataClearer(browser_context, origin, clear_site_data_types, - storage_buckets_to_remove, avoid_closing_connections, - cookie_partition_key, storage_key, - partitioned_state_allowed_only, std::move(callback))) + (new SiteDataClearer(browser_context, storage_partition_config, origin, + clear_site_data_types, storage_buckets_to_remove, + avoid_closing_connections, cookie_partition_key, + storage_key, partitioned_state_allowed_only, + std::move(callback))) ->RunAndDestroySelfWhenDone(); }
diff --git a/content/browser/interest_group/ad_auction_service_impl.cc b/content/browser/interest_group/ad_auction_service_impl.cc index 88aaf25..2f9accc 100644 --- a/content/browser/interest_group/ad_auction_service_impl.cc +++ b/content/browser/interest_group/ad_auction_service_impl.cc
@@ -600,28 +600,30 @@ bool AdAuctionServiceImpl::JoinOrLeaveApiAllowedFromRenderer( const url::Origin& owner) { + if (origin().scheme() != url::kHttpsScheme) { + ReportBadMessageAndDeleteThis( + "Unexpected request: Interest groups may only be joined or left from " + "https origins"); + return false; + } + // If the interest group API is not allowed for this context by Permissions // Policy, do nothing if (!render_frame_host().IsFeatureEnabled( blink::mojom::PermissionsPolicyFeature::kJoinAdInterestGroup)) { - ReportBadMessageAndDeleteThis("Unexpected request"); + ReportBadMessageAndDeleteThis( + "Unexpected request: Interest groups may only be joined or left when " + "feature join-ad-interest-group is enabled by Permissions Policy"); return false; } if (owner.scheme() != url::kHttpsScheme) { ReportBadMessageAndDeleteThis( - "Unexpected request: Interest groups may only be owned by secure " + "Unexpected request: Interest groups may only be owned by https " "origins"); return false; } - if (origin().scheme() != url::kHttpsScheme) { - ReportBadMessageAndDeleteThis( - "Unexpected request: Interest groups may only be joined or left from " - "secure origins"); - return false; - } - return true; }
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc index e9758756..f014994 100644 --- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc +++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "ad_auction_page_data.h" #include "base/barrier_closure.h" #include "base/base64.h" #include "base/command_line.h"
diff --git a/content/browser/interest_group/additional_bids_util.cc b/content/browser/interest_group/additional_bids_util.cc new file mode 100644 index 0000000..56776ea --- /dev/null +++ b/content/browser/interest_group/additional_bids_util.cc
@@ -0,0 +1,257 @@ +// 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 "content/browser/interest_group/additional_bids_util.h" + +#include <memory> +#include <string> + +#include "base/json/json_writer.h" +#include "base/strings/strcat.h" +#include "base/time/time.h" +#include "base/types/optional_ref.h" +#include "base/uuid.h" +#include "base/values.h" +#include "content/browser/interest_group/interest_group_auction.h" +#include "content/common/content_export.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/interest_group/ad_display_size.h" +#include "url/origin.h" + +namespace content { + +AdditionalBidDecodeResult::AdditionalBidDecodeResult() = default; +AdditionalBidDecodeResult::AdditionalBidDecodeResult( + AdditionalBidDecodeResult&& other) = default; +AdditionalBidDecodeResult::~AdditionalBidDecodeResult() = default; + +AdditionalBidDecodeResult& AdditionalBidDecodeResult::operator=( + AdditionalBidDecodeResult&&) = default; + +base::expected<AdditionalBidDecodeResult, std::string> DecodeAdditionalBid( + InterestGroupAuction* auction, + const base::Value& bid_in, + const base::Uuid& auction_nonce, + const url::Origin& seller, + base::optional_ref<const url::Origin> top_level_seller) { + const base::Value::Dict* result_dict = bid_in.GetIfDict(); + if (!result_dict) { + return base::unexpected( + base::StrCat({"Additional bid on auction with seller '", + seller.Serialize(), "' is not a dictionary."})); + } + + const std::string* nonce = result_dict->FindString("auctionNonce"); + if (!nonce || *nonce != auction_nonce.AsLowercaseString()) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing or incorrect nonce."})); + } + + const std::string* bid_seller = result_dict->FindString("seller"); + if (!bid_seller || url::Origin::Create(GURL(*bid_seller)) != seller) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing or incorrect seller."})); + } + + const std::string* bid_top_level_seller = + result_dict->FindString("topLevelSeller"); + if (top_level_seller.has_value()) { + // Component auction. + if (!bid_top_level_seller || + url::Origin::Create(GURL(*bid_top_level_seller)) != *top_level_seller) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing or incorrect topLevelSeller."})); + } + } else { + // Top-level or single-level auction. + if (bid_top_level_seller) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to specifying topLevelSeller in a non-component " + "auction."})); + } + } + + const std::string* ig_name = + result_dict->FindStringByDottedPath("interestGroup.name"); + const std::string* ig_bidding_url_str = + result_dict->FindStringByDottedPath("interestGroup.biddingLogicURL"); + const std::string* ig_owner_string = + result_dict->FindStringByDottedPath("interestGroup.owner"); + + GURL ig_bidding_url; + if (ig_bidding_url_str) { + ig_bidding_url = GURL(*ig_bidding_url_str); + } + + absl::optional<url::Origin> ig_owner; + if (ig_owner_string) { + GURL ig_owner_url(*ig_owner_string); + if (ig_owner_url.is_valid() && ig_owner_url.SchemeIs("https")) { + ig_owner = url::Origin::Create(ig_owner_url); + } + } + + if (!ig_name || !ig_bidding_url.is_valid() || !ig_owner.has_value()) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing or invalid interest group info."})); + } + + if (!ig_owner->IsSameOriginWith(ig_bidding_url)) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to invalid origin of biddingLogicURL."})); + } + + auto synth_interest_group = std::make_unique<StorageInterestGroup>(); + synth_interest_group->interest_group.owner = + url::Origin::Create(ig_bidding_url); + synth_interest_group->interest_group.name = *ig_name; + synth_interest_group->interest_group.owner = std::move(ig_owner).value(); + synth_interest_group->interest_group.bidding_url = std::move(ig_bidding_url); + + // Add ads. + const base::Value::Dict* bid_dict = result_dict->FindDict("bid"); + if (!bid_dict) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing bid info."})); + } + + const std::string* render_url_str = bid_dict->FindString("render"); + GURL render_url; + if (render_url_str) { + render_url = GURL(*render_url_str); + } + if (!render_url.is_valid()) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing or invalid creative URL."})); + } + + // Create ad vector and its first entry. + synth_interest_group->interest_group.ads.emplace(); + synth_interest_group->interest_group.ads.value().emplace_back(); + synth_interest_group->interest_group.ads.value()[0].render_url = render_url; + + absl::optional<double> bid_val = bid_dict->FindDouble("bid"); + if (!bid_val || bid_val.value() <= 0) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to missing or invalid bid value."})); + } + + std::string ad_metadata = "null"; + const base::Value* ad_metadata_val = bid_dict->Find("ad"); + if (ad_metadata_val) { + absl::optional<std::string> serialized_metadata = + base::WriteJson(*ad_metadata_val); + if (serialized_metadata) { + ad_metadata = std::move(serialized_metadata).value(); + } + } + + absl::optional<blink::AdCurrency> bid_currency; + const base::Value* bid_currency_val = bid_dict->Find("bidCurrency"); + if (bid_currency_val) { + const std::string* bid_currency_str = bid_currency_val->GetIfString(); + if (!bid_currency_str || !blink::IsValidAdCurrencyCode(*bid_currency_str)) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to invalid bidCurrency."})); + } else { + bid_currency = blink::AdCurrency::From(*bid_currency_str); + } + } + // TODO(http://crbug.com/1464874): How do we check against per-buyer-currency? + + absl::optional<double> ad_cost; + const base::Value* ad_cost_val = bid_dict->Find("adCost"); + if (ad_cost_val) { + ad_cost = ad_cost_val->GetIfDouble(); + if (!ad_cost.has_value()) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to invalid adCost."})); + } + } + + // modelingSignals in generateBid() ignores out-of-range values, so this + // matches the behavior. + absl::optional<double> modeling_signals; + const base::Value* modeling_signals_val = bid_dict->Find("modelingSignals"); + if (modeling_signals_val) { + absl::optional<double> modeling_signals_in = + modeling_signals_val->GetIfDouble(); + if (!modeling_signals_in.has_value()) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to non-numeric modelingSignals."})); + } + if (*modeling_signals_in >= 0 && *modeling_signals_in < 4096) { + modeling_signals = modeling_signals_in; + } + } + + std::vector<blink::AdDescriptor> ad_components; + const base::Value* ad_components_val = bid_dict->Find("adComponents"); + if (ad_components_val) { + const base::Value::List* ad_components_list = + ad_components_val->GetIfList(); + if (!ad_components_list) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to invalid adComponents."})); + } + synth_interest_group->interest_group.ad_components.emplace(); + for (const base::Value& ad_component : *ad_components_list) { + const std::string* ad_component_str = ad_component.GetIfString(); + GURL ad_component_url; + if (ad_component_str) { + ad_component_url = GURL(*ad_component_str); + } + if (!ad_component_url.is_valid()) { + return base::unexpected(base::StrCat( + {"Additional bid on auction with seller '", seller.Serialize(), + "' rejected due to invalid entry in adComponents."})); + } + ad_components.emplace_back(ad_component_url); + // TODO(http://crbug.com/1464874): What's the story with dimensions? + synth_interest_group->interest_group.ad_components->emplace_back( + std::move(ad_component_url), /*metadata=*/absl::nullopt); + } + } + + AdditionalBidDecodeResult result; + result.bid_state = std::make_unique<InterestGroupAuction::BidState>(); + result.bid_state->bidder = std::move(synth_interest_group); + result.bid_state->made_bid = true; + result.bid_state->BeginTracing(); + + const blink::InterestGroup::Ad* bid_ad = + &result.bid_state->bidder->interest_group.ads.value()[0]; + result.bid = std::make_unique<InterestGroupAuction::Bid>( + InterestGroupAuction::Bid::BidRole::kBothKAnonModes, ad_metadata, + *bid_val, + /*bid_currency=*/bid_currency, + /*ad_cost=*/ad_cost, + /*ad_descriptor=*/blink::AdDescriptor(bid_ad->render_url), + /*ad_component_descriptors=*/std::move(ad_components), + /*modeling_signals=*/ + static_cast<absl::optional<uint16_t>>(modeling_signals), + /*bid_duration=*/base::TimeDelta(), + /*bidding_signals_data_version=*/absl::nullopt, bid_ad, + result.bid_state.get(), auction); + + // TODO(http://crbug.com/1464874): Do we need to fill in any k-anon info? + // TODO(http://crbug.com/1464874): Parse the actual negative targeting info. + + return result; +} + +} // namespace content
diff --git a/content/browser/interest_group/additional_bids_util.h b/content/browser/interest_group/additional_bids_util.h new file mode 100644 index 0000000..575637f --- /dev/null +++ b/content/browser/interest_group/additional_bids_util.h
@@ -0,0 +1,61 @@ +// 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 CONTENT_BROWSER_INTEREST_GROUP_ADDITIONAL_BIDS_UTIL_H_ +#define CONTENT_BROWSER_INTEREST_GROUP_ADDITIONAL_BIDS_UTIL_H_ + +#include <string> + +#include "base/types/expected.h" +#include "base/types/optional_ref.h" +#include "base/uuid.h" +#include "base/values.h" +#include "content/browser/interest_group/interest_group_auction.h" +#include "content/common/content_export.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/origin.h" + +namespace content { + +struct CONTENT_EXPORT AdditionalBidDecodeResult { + AdditionalBidDecodeResult(); + AdditionalBidDecodeResult(const AdditionalBidDecodeResult& other) = delete; + AdditionalBidDecodeResult(AdditionalBidDecodeResult&& other); + ~AdditionalBidDecodeResult(); + + AdditionalBidDecodeResult& operator=(const AdditionalBidDecodeResult&) = + delete; + AdditionalBidDecodeResult& operator=(AdditionalBidDecodeResult&&); + + std::unique_ptr<InterestGroupAuction::BidState> bid_state; + std::unique_ptr<InterestGroupAuction::Bid> bid; +}; + +// Tries to parse a "bid" object `bid_in` specified as part of "additionalBids", +// and to construct corresponding InterestGroupAuction::Bid and BidState. +// +// `auction` will only be used to populate the `auction` field of the +// returned result's `bid`, so may be null for tests. +// +// `auction_nonce` is the expected nonce for the bid. +// +// `seller` is expected seller for the auction the bid is to participate in. +// +// `top_level_seller` should be set for the component auctions only, and specify +// the seller of the enclosing top-level auction. +// +// On success, returns an AdditionalBidDecodeResult. Note that `*bid` will +// have a pointer to `*bid_state`. +// +// On failure, returns an error message. +CONTENT_EXPORT base::expected<AdditionalBidDecodeResult, std::string> +DecodeAdditionalBid(InterestGroupAuction* auction, + const base::Value& bid_in, + const base::Uuid& auction_nonce, + const url::Origin& seller, + base::optional_ref<const url::Origin> top_level_seller); + +} // namespace content + +#endif // CONTENT_BROWSER_INTEREST_GROUP_ADDITIONAL_BIDS_UTIL_H_
diff --git a/content/browser/interest_group/additional_bids_util_unittest.cc b/content/browser/interest_group/additional_bids_util_unittest.cc new file mode 100644 index 0000000..471e247 --- /dev/null +++ b/content/browser/interest_group/additional_bids_util_unittest.cc
@@ -0,0 +1,633 @@ +// 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 "content/browser/interest_group/additional_bids_util.h" + +#include <limits> +#include <string> + +#include "base/types/optional_ref.h" +#include "base/uuid.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/interest_group/ad_display_size.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace content { +namespace { + +class AdditionalBidsUtilTest : public testing::Test { + protected: + base::Value::Dict MakeMinimalValid() { + base::Value::Dict ig_dict; + ig_dict.Set("name", "trainfans"); + ig_dict.Set("biddingLogicURL", "https://rollingstock.test/logic.js"); + ig_dict.Set("owner", "https://rollingstock.test/"); + + base::Value::Dict bid_dict; + bid_dict.Set("bid", 10.0); + bid_dict.Set("render", "https://en.wikipedia.test/wiki/Train"); + + base::Value::Dict additional_bid_dict; + additional_bid_dict.Set("auctionNonce", kAuctionNonce.AsLowercaseString()); + additional_bid_dict.Set("seller", "https://seller.test"); + additional_bid_dict.Set("topLevelSeller", "https://top-organizer.test"); + additional_bid_dict.Set("interestGroup", std::move(ig_dict)); + additional_bid_dict.Set("bid", std::move(bid_dict)); + return additional_bid_dict; + } + + const base::Uuid kAuctionNonce{base::Uuid::GenerateRandomV4()}; + const url::Origin kSeller = url::Origin::Create(GURL("https://seller.test")); + const url::Origin kTopSeller = + url::Origin::Create(GURL("https://top-organizer.test")); +}; + +TEST_F(AdditionalBidsUtilTest, FailNotDict) { + base::Value input(5); + + auto result = + DecodeAdditionalBid(/*auction=*/nullptr, input, kAuctionNonce, kSeller, + /*top_level_seller=*/absl::nullopt); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' is not a " + "dictionary.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailNoNonce) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Remove("auctionNonce"); + base::Value input(std::move(additional_bid_dict)); + + auto result = + DecodeAdditionalBid(/*auction=*/nullptr, input, kAuctionNonce, kSeller, + /*top_level_seller=*/absl::nullopt); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or incorrect nonce.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailInvalidNonce) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Set("auctionNonce", "not-a-nonce"); + base::Value input(std::move(additional_bid_dict)); + + auto result = + DecodeAdditionalBid(/*auction=*/nullptr, input, kAuctionNonce, kSeller, + /*top_level_seller=*/absl::nullopt); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or incorrect nonce.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailMissingSeller) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Remove("seller"); + base::Value input(std::move(additional_bid_dict)); + + auto result = + DecodeAdditionalBid(/*auction=*/nullptr, input, kAuctionNonce, kSeller, + /*top_level_seller=*/absl::nullopt); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or incorrect seller.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailInvalidSeller) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Set("seller", "http://notseller.test"); + base::Value input(std::move(additional_bid_dict)); + + auto result = + DecodeAdditionalBid(/*auction=*/nullptr, input, kAuctionNonce, kSeller, + /*top_level_seller=*/absl::nullopt); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or incorrect seller.", + result.error()); +} + +// Specifying topLevelSeller in a bid in a non-component auction is a problem. +TEST_F(AdditionalBidsUtilTest, FailInvalidTopLevelSeller) { + base::Value input(MakeMinimalValid()); + auto result = + DecodeAdditionalBid(/*auction=*/nullptr, input, kAuctionNonce, kSeller, + /*top_level_seller=*/absl::nullopt); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to specifying topLevelSeller in a non-component auction.", + result.error()); +} + +// Not specifying topLevelSeller in component auction bid is also a problem. +TEST_F(AdditionalBidsUtilTest, FailInvalidTopLevelSeller2) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Remove("topLevelSeller"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or incorrect topLevelSeller.", + result.error()); +} + +// An incorrect topLevelSeller in a bid in a component auction is also a +// problem. +TEST_F(AdditionalBidsUtilTest, FailInvalidTopLevelSeller3) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Set("topLevelSeller", "https://wrong-organizer.test"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or incorrect topLevelSeller.", + result.error()); +} + +// Missing IG dictionary. +TEST_F(AdditionalBidsUtilTest, FailNoIGDictionary) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Remove("interestGroup"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid interest group info.", + result.error()); +} + +// Missing IG name. +TEST_F(AdditionalBidsUtilTest, FailInvalidIG) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.RemoveByDottedPath("interestGroup.name"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid interest group info.", + result.error()); +} + +// Missing IG bidding script. +TEST_F(AdditionalBidsUtilTest, FailInvalidIG2) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.RemoveByDottedPath("interestGroup.biddingLogicURL"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid interest group info.", + result.error()); +} + +// Missing IG owner. +TEST_F(AdditionalBidsUtilTest, FailInvalidIG3) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.RemoveByDottedPath("interestGroup.owner"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid interest group info.", + result.error()); +} + +// Non-https IG owner. +TEST_F(AdditionalBidsUtilTest, FailInvalidIG4) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("interestGroup.owner", + "http://rollingstock.test/"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid interest group info.", + result.error()); +} + +// Domain mismatch between owner and bidding script. +TEST_F(AdditionalBidsUtilTest, FailInvalidIG5) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("interestGroup.owner", + "https://trainstuff.test/"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to invalid origin of biddingLogicURL.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailMissingBid) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.Remove("bid"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing bid info.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailMissingBidCreative) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.RemoveByDottedPath("bid.render"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid creative URL.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailMissingBidValue) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.RemoveByDottedPath("bid.bid"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid bid value.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, FailInvalidBidValue) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.bid", 0.0); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to missing or invalid bid value.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, MinimalValid) { + base::Value input(MakeMinimalValid()); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid_state); + ASSERT_TRUE(result->bid); + const InterestGroupAuction::BidState* bid_state = result->bid_state.get(); + const InterestGroupAuction::Bid* bid = result->bid.get(); + + EXPECT_TRUE(bid_state->made_bid); + ASSERT_TRUE(bid_state->bidder); + EXPECT_EQ("trainfans", bid_state->bidder->interest_group.name); + EXPECT_EQ("https://rollingstock.test", + bid_state->bidder->interest_group.owner.Serialize()); + ASSERT_TRUE(bid_state->bidder->interest_group.bidding_url.has_value()); + EXPECT_EQ("https://rollingstock.test/logic.js", + bid_state->bidder->interest_group.bidding_url->spec()); + + ASSERT_TRUE(bid_state->bidder->interest_group.ads.has_value()); + ASSERT_EQ(1u, bid_state->bidder->interest_group.ads->size()); + EXPECT_EQ("https://en.wikipedia.test/wiki/Train", + bid_state->bidder->interest_group.ads.value()[0].render_url.spec()); + + EXPECT_EQ(InterestGroupAuction::Bid::BidRole::kBothKAnonModes, bid->bid_role); + EXPECT_EQ("null", bid->ad_metadata); + EXPECT_EQ(10.0, bid->bid); + EXPECT_EQ(absl::nullopt, bid->bid_currency); + EXPECT_EQ(absl::nullopt, bid->ad_cost); + EXPECT_EQ(blink::AdDescriptor(GURL("https://en.wikipedia.test/wiki/Train")), + bid->ad_descriptor); + EXPECT_EQ(0u, bid->ad_component_descriptors.size()); + EXPECT_EQ(absl::nullopt, bid->modeling_signals); + EXPECT_EQ(&bid_state->bidder->interest_group, bid->interest_group); + EXPECT_EQ(&bid_state->bidder->interest_group.ads.value()[0], bid->bid_ad); + EXPECT_EQ(bid_state, bid->bid_state); +} + +TEST_F(AdditionalBidsUtilTest, InvalidBidCurrencyType) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.bidCurrency", 5); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to invalid bidCurrency.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, InvalidBidCurrencySyntax) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.bidCurrency", "Dollars"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to invalid bidCurrency.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, ValidBidCurrency) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.bidCurrency", "USD"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + EXPECT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid->bid_currency); + EXPECT_EQ("USD", result->bid->bid_currency->currency_code()); +} + +TEST_F(AdditionalBidsUtilTest, InvalidAdCost) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.adCost", "big"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to invalid adCost.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, ValidAdCost) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.adCost", 15.5); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid->ad_cost); + EXPECT_EQ(15.5, *result->bid->ad_cost); +} + +// We have a tradition of ignoring modeling signals if they're out of range, +// so this follows. +TEST_F(AdditionalBidsUtilTest, InvalidModelingSignals) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.modelingSignals", 4096); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + EXPECT_FALSE(result->bid->modeling_signals); +} + +TEST_F(AdditionalBidsUtilTest, InvalidModelingSignals2) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.modelingSignals", -0.001); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + EXPECT_FALSE(result->bid->modeling_signals); +} + +// Bad-type modeling signals still an error, however. +TEST_F(AdditionalBidsUtilTest, BadTypeModelingSignals) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.modelingSignals", "string"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to non-numeric modelingSignals.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, ValidModelingSignals) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.modelingSignals", 0); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid->modeling_signals); + EXPECT_EQ(*result->bid->modeling_signals, 0); +} + +TEST_F(AdditionalBidsUtilTest, ValidModelingSignals2) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.modelingSignals", 2.5); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid->modeling_signals); + EXPECT_EQ(*result->bid->modeling_signals, 2); +} + +TEST_F(AdditionalBidsUtilTest, ValidModelingSignals3) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.modelingSignals", 4095.5); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid->modeling_signals); + EXPECT_EQ(*result->bid->modeling_signals, 4095); +} + +TEST_F(AdditionalBidsUtilTest, InvalidAdComponents) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + additional_bid_dict.SetByDottedPath("bid.adComponents", "oops"); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to invalid adComponents.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, InvalidAdComponentsEntry) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + base::Value::List ad_components_list; + ad_components_list.Append(10); + additional_bid_dict.SetByDottedPath("bid.adComponents", + std::move(ad_components_list)); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ( + "Additional bid on auction with seller 'https://seller.test' rejected " + "due to invalid entry in adComponents.", + result.error()); +} + +TEST_F(AdditionalBidsUtilTest, ValidAdComponents) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + base::Value::List ad_components_list; + ad_components_list.Append("https://en.wikipedia.test/wiki/Locomotive"); + ad_components_list.Append("https://en.wikipedia.test/wiki/High-speed_rail"); + additional_bid_dict.SetByDottedPath("bid.adComponents", + std::move(ad_components_list)); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid_state); + + // Components should be both in the ad and the synthesized IG. + ASSERT_EQ(2u, result->bid->ad_component_descriptors.size()); + EXPECT_EQ( + blink::AdDescriptor(GURL("https://en.wikipedia.test/wiki/Locomotive")), + result->bid->ad_component_descriptors[0]); + EXPECT_EQ(blink::AdDescriptor( + GURL("https://en.wikipedia.test/wiki/High-speed_rail")), + result->bid->ad_component_descriptors[1]); + + ASSERT_TRUE( + result->bid_state->bidder->interest_group.ad_components.has_value()); + ASSERT_EQ(2u, + result->bid_state->bidder->interest_group.ad_components->size()); + EXPECT_EQ("https://en.wikipedia.test/wiki/Locomotive", + result->bid_state->bidder->interest_group.ad_components.value()[0] + .render_url.spec()); + EXPECT_EQ("https://en.wikipedia.test/wiki/High-speed_rail", + result->bid_state->bidder->interest_group.ad_components.value()[1] + .render_url.spec()); +} + +TEST_F(AdditionalBidsUtilTest, ValidAdComponentsEmpty) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + base::Value::List ad_components_list; + additional_bid_dict.SetByDottedPath("bid.adComponents", + std::move(ad_components_list)); + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + ASSERT_TRUE(result->bid_state); + + EXPECT_EQ(0u, result->bid->ad_component_descriptors.size()); + ASSERT_TRUE( + result->bid_state->bidder->interest_group.ad_components.has_value()); + EXPECT_EQ(0u, + result->bid_state->bidder->interest_group.ad_components->size()); +} + +TEST_F(AdditionalBidsUtilTest, ValidAdMetadata) { + base::Value::Dict additional_bid_dict = MakeMinimalValid(); + base::Value::Dict metadata_dict; + metadata_dict.Set("a", "hello"); + metadata_dict.Set("b", 1.0); + additional_bid_dict.SetByDottedPath("bid.ad", std::move(metadata_dict)); + + base::Value input(std::move(additional_bid_dict)); + + auto result = DecodeAdditionalBid( + /*auction=*/nullptr, input, kAuctionNonce, kSeller, + base::optional_ref<const url::Origin>(kTopSeller)); + EXPECT_TRUE(result.has_value()); + ASSERT_TRUE(result->bid); + EXPECT_EQ(R"({"a":"hello","b":1.0})", result->bid->ad_metadata); +} + +} // namespace +} // namespace content
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc index c5223b9..d8561da 100644 --- a/content/browser/interest_group/interest_group_auction.cc +++ b/content/browser/interest_group/interest_group_auction.cc
@@ -325,6 +325,171 @@ return it->second; } +// Takes private aggregation requests for `state`, if there are any, and moves +// them into `private_aggregation_requests_reserved` and +// `private_aggregation_requests_non_reserved`. +// +// Calculates bucket/value using `signals` and `top_level_signals` as needed. +// +// `winner` points to the BidState associated with the winning bid, if there +// is one. +// +// `signals` are the PostAuctionSignals from the auction `state` was a part of. +void TakePrivateAggregationRequestsForBidState( + std::unique_ptr<InterestGroupAuction::BidState>& state, + bool is_component_auction, + const InterestGroupAuction::BidState* winner, + const InterestGroupAuction::BidState* non_kanon_winner, + const InterestGroupAuction::PostAuctionSignals& signals, + const absl::optional<InterestGroupAuction::PostAuctionSignals>& + top_level_signals, + std::map<url::Origin, + InterestGroupAuctionReporter::PrivateAggregationRequests>& + private_aggregation_requests_reserved, + std::map<std::string, + InterestGroupAuctionReporter::PrivateAggregationRequests>& + private_aggregation_requests_non_reserved) { + bool is_winner = state.get() == winner; + for (auto& [key, requests] : state->private_aggregation_requests) { + const url::Origin& origin = key.first; + InterestGroupAuction::PrivateAggregationPhase phase = key.second; + double winning_bid_to_use = signals.winning_bid; + double highest_scoring_other_bid_to_use = signals.highest_scoring_other_bid; + // When component auctions are in use, a BuyerHelper for a component + // auction calls here for the scoreAd() aggregation calls from the + // top-level; in that case the relevant signals are in + // `top_level_signals` and not `signals`. `highest_scoring_other_bid` + // is also not reported for top-levels. + if (phase == + InterestGroupAuction::PrivateAggregationPhase::kTopLevelSeller && + is_component_auction) { + highest_scoring_other_bid_to_use = 0; + winning_bid_to_use = + top_level_signals.has_value() ? top_level_signals->winning_bid : 0.0; + } + + for (auction_worklet::mojom::PrivateAggregationRequestPtr& request : + requests) { + absl::optional<PrivateAggregationRequestWithEventType> converted_request = + FillInPrivateAggregationRequest( + std::move(request), winning_bid_to_use, + highest_scoring_other_bid_to_use, state->reject_reason, + state->pa_timings(phase), is_winner); + if (converted_request.has_value()) { + PrivateAggregationRequestWithEventType converted_request_value = + std::move(converted_request.value()); + const absl::optional<std::string>& event_type = + converted_request_value.event_type; + if (event_type.has_value()) { + // The request has a non-reserved event type. + private_aggregation_requests_non_reserved[event_type.value()] + .emplace_back(std::move(converted_request_value.request)); + } else { + private_aggregation_requests_reserved[origin].emplace_back( + std::move(converted_request_value.request)); + } + } + } + } + if (non_kanon_winner == state.get()) { + const url::Origin& bidder = state->bidder->interest_group.owner; + for (auction_worklet::mojom::PrivateAggregationRequestPtr& request : + state->non_kanon_private_aggregation_requests) { + absl::optional<PrivateAggregationRequestWithEventType> converted_request = + FillInPrivateAggregationRequest( + std::move(request), signals.winning_bid, + signals.highest_scoring_other_bid, + auction_worklet::mojom::RejectReason::kBelowKAnonThreshold, + state->pa_timings( + InterestGroupAuction::PrivateAggregationPhase::kBidder), + false); + if (converted_request.has_value()) { + PrivateAggregationRequestWithEventType converted_request_value = + std::move(converted_request.value()); + // Only reserved types are supported for k-anon failures. + // This *should* be guaranteed by `FillInPrivateAggregationRequest` + // since we passed in `false` for `is_winner`. + DCHECK(!converted_request_value.event_type.has_value()); + private_aggregation_requests_reserved[bidder].emplace_back( + std::move(converted_request_value.request)); + } + } + } +} + +// Adds debug reporting URLs for `bid_state` to `debug_win_report_urls` and +// `debug_loss_report_urls`, if there are any, filling in report URL template +// parameters as needed. The URLs are moved away from `bid_state`. +// +// `winner` points to the BidState associated with the winning bid, if there +// is one. +// +// `signals` are the PostAuctionSignals from the auction `state` was a part of. +// +// `top_level_signals` are the PostAuctionSignals of the top-level auction, if +// the computation is for a component auction, and nullopt otherwise. +void TakeDebugReportUrlsForBidState( + std::unique_ptr<InterestGroupAuction::BidState>& bid_state, + const InterestGroupAuction::BidState* winner, + const InterestGroupAuction::PostAuctionSignals& signals, + const absl::optional<InterestGroupAuction::PostAuctionSignals>& + top_level_signals, + std::vector<GURL>& debug_win_report_urls, + std::vector<GURL>& debug_loss_report_urls) { + if (bid_state.get() == winner) { + if (winner->bidder_debug_win_report_url.has_value()) { + debug_win_report_urls.emplace_back( + InterestGroupAuction::FillPostAuctionSignals( + std::move(winner->bidder_debug_win_report_url).value(), signals)); + } + if (winner->seller_debug_win_report_url.has_value()) { + debug_win_report_urls.emplace_back( + InterestGroupAuction::FillPostAuctionSignals( + std::move(winner->seller_debug_win_report_url).value(), signals, + top_level_signals)); + } + // `top_level_signals` is passed as parameter `signals` for top-level + // seller. + if (winner->top_level_seller_debug_win_report_url.has_value()) { + debug_win_report_urls.emplace_back( + InterestGroupAuction::FillPostAuctionSignals( + std::move(winner->top_level_seller_debug_win_report_url).value(), + top_level_signals.value())); + } + return; + } + if (bid_state->bidder_debug_loss_report_url.has_value()) { + // Losing and rejected bidders should not get highest_scoring_other_bid + // and made_highest_scoring_other_bid signals. (And also the currency + // bit for those). + debug_loss_report_urls.emplace_back( + InterestGroupAuction::FillPostAuctionSignals( + std::move(bid_state->bidder_debug_loss_report_url).value(), + InterestGroupAuction::PostAuctionSignals( + signals.winning_bid, signals.winning_bid_currency, + signals.made_winning_bid, /*highest_scoring_other_bid=*/0.0, + /*highest_scoring_other_bid_currency=*/absl::nullopt, + /*made_highest_scoring_other_bid=*/false), + /*top_level_signals=*/absl::nullopt, bid_state->reject_reason)); + } + // TODO(qingxinwu): Add reject reason to seller debug loss report as well. + if (bid_state->seller_debug_loss_report_url.has_value()) { + debug_loss_report_urls.emplace_back( + InterestGroupAuction::FillPostAuctionSignals( + std::move(bid_state->seller_debug_loss_report_url).value(), signals, + top_level_signals)); + } + // `top_level_signals` is passed as parameter `signals` for top-level + // seller. + if (bid_state->top_level_seller_debug_loss_report_url.has_value()) { + debug_loss_report_urls.emplace_back( + InterestGroupAuction::FillPostAuctionSignals( + std::move(bid_state->top_level_seller_debug_loss_report_url) + .value(), + top_level_signals.value())); + } +} + // Retrieves the timeout from `buyer_timeouts` associated with `buyer`, if any. // Used for both `buyer_timeouts` and `buyer_cumulative_timeouts`, stored in // AuctionConfigs. Callers should use PerBuyerTimeout() and @@ -837,52 +1002,9 @@ std::vector<GURL>& debug_win_report_urls, std::vector<GURL>& debug_loss_report_urls) { for (std::unique_ptr<BidState>& bid_state : bid_states_) { - if (bid_state.get() == winner) { - if (winner->bidder_debug_win_report_url.has_value()) { - debug_win_report_urls.emplace_back(FillPostAuctionSignals( - std::move(winner->bidder_debug_win_report_url).value(), signals)); - } - if (winner->seller_debug_win_report_url.has_value()) { - debug_win_report_urls.emplace_back(FillPostAuctionSignals( - std::move(winner->seller_debug_win_report_url).value(), signals, - top_level_signals)); - } - // `top_level_signals` is passed as parameter `signals` for top-level - // seller. - if (winner->top_level_seller_debug_win_report_url.has_value()) { - debug_win_report_urls.emplace_back(FillPostAuctionSignals( - std::move(winner->top_level_seller_debug_win_report_url).value(), - top_level_signals.value())); - } - continue; - } - if (bid_state->bidder_debug_loss_report_url.has_value()) { - // Losing and rejected bidders should not get highest_scoring_other_bid - // and made_highest_scoring_other_bid signals. (And also the currency - // bit for those). - debug_loss_report_urls.emplace_back(FillPostAuctionSignals( - std::move(bid_state->bidder_debug_loss_report_url).value(), - PostAuctionSignals( - signals.winning_bid, signals.winning_bid_currency, - signals.made_winning_bid, /*highest_scoring_other_bid=*/0.0, - /*highest_scoring_other_bid_currency=*/absl::nullopt, - /*made_highest_scoring_other_bid=*/false), - /*top_level_signals=*/absl::nullopt, bid_state->reject_reason)); - } - // TODO(qingxinwu): Add reject reason to seller debug loss report as well. - if (bid_state->seller_debug_loss_report_url.has_value()) { - debug_loss_report_urls.emplace_back(FillPostAuctionSignals( - std::move(bid_state->seller_debug_loss_report_url).value(), signals, - top_level_signals)); - } - // `top_level_signals` is passed as parameter `signals` for top-level - // seller. - if (bid_state->top_level_seller_debug_loss_report_url.has_value()) { - debug_loss_report_urls.emplace_back(FillPostAuctionSignals( - std::move(bid_state->top_level_seller_debug_loss_report_url) - .value(), - top_level_signals.value())); - } + TakeDebugReportUrlsForBidState(bid_state, winner, signals, + top_level_signals, debug_win_report_urls, + debug_loss_report_urls); } } @@ -903,71 +1025,11 @@ std::map<std::string, PrivateAggregationRequests>& private_aggregation_requests_non_reserved) { for (std::unique_ptr<BidState>& state : bid_states_) { - bool is_winner = state.get() == winner; - for (auto& [key, requests] : state->private_aggregation_requests) { - const url::Origin& origin = key.first; - PrivateAggregationPhase phase = key.second; - double winning_bid_to_use = signals.winning_bid; - double highest_scoring_other_bid_to_use = - signals.highest_scoring_other_bid; - // When component auctions are in use, a BuyerHelper for a component - // auction calls here for the scoreAd() aggregation calls from the - // top-level; in that case the relevant signals are in - // `top_level_signals` and not `signals`. `highest_scoring_other_bid` - // is also not reported for top-levels. - if (phase == PrivateAggregationPhase::kTopLevelSeller && - auction_->parent_) { - highest_scoring_other_bid_to_use = 0; - winning_bid_to_use = top_level_signals.has_value() - ? top_level_signals->winning_bid - : 0.0; - } - - for (auction_worklet::mojom::PrivateAggregationRequestPtr& request : - requests) { - absl::optional<PrivateAggregationRequestWithEventType> - converted_request = FillInPrivateAggregationRequest( - std::move(request), winning_bid_to_use, - highest_scoring_other_bid_to_use, state->reject_reason, - state->pa_timings(phase), is_winner); - if (converted_request.has_value()) { - PrivateAggregationRequestWithEventType converted_request_value = - std::move(converted_request.value()); - const absl::optional<std::string>& event_type = - converted_request_value.event_type; - if (event_type.has_value()) { - // The request has a non-reserved event type. - private_aggregation_requests_non_reserved[event_type.value()] - .emplace_back(std::move(converted_request_value.request)); - } else { - private_aggregation_requests_reserved[origin].emplace_back( - std::move(converted_request_value.request)); - } - } - } - } - if (non_kanon_winner == state.get()) { - const url::Origin& bidder = state->bidder->interest_group.owner; - for (auction_worklet::mojom::PrivateAggregationRequestPtr& request : - state->non_kanon_private_aggregation_requests) { - absl::optional<PrivateAggregationRequestWithEventType> - converted_request = FillInPrivateAggregationRequest( - std::move(request), signals.winning_bid, - signals.highest_scoring_other_bid, - auction_worklet::mojom::RejectReason::kBelowKAnonThreshold, - state->pa_timings(PrivateAggregationPhase::kBidder), false); - if (converted_request.has_value()) { - PrivateAggregationRequestWithEventType converted_request_value = - std::move(converted_request.value()); - // Only reserved types are supported for k-anon failures. - // This *should* be guaranteed by `FillInPrivateAggregationRequest` - // since we passed in `false` for `is_winner`. - DCHECK(!converted_request_value.event_type.has_value()); - private_aggregation_requests_reserved[bidder].emplace_back( - std::move(converted_request_value.request)); - } - } - } + TakePrivateAggregationRequestsForBidState( + state, /*is_component_auction=*/auction_->parent_, winner, + non_kanon_winner, signals, top_level_signals, + private_aggregation_requests_reserved, + private_aggregation_requests_non_reserved); } }
diff --git a/content/browser/interest_group/interest_group_auction.h b/content/browser/interest_group/interest_group_auction.h index 6489839e..dda380b 100644 --- a/content/browser/interest_group/interest_group_auction.h +++ b/content/browser/interest_group/interest_group_auction.h
@@ -164,7 +164,7 @@ kNumPhases }; - struct BidState { + struct CONTENT_EXPORT BidState { BidState(); ~BidState(); @@ -321,7 +321,7 @@ // and is persisted to the end of the auction if the bidder wins. Largely // duplicates auction_worklet::mojom::BidderWorkletBid, with additional // information about the bidder. - struct Bid { + struct CONTENT_EXPORT Bid { // Which auctions the bid is appropriate for, based on whether the auction // enforces k-anonymity or not. enum class BidRole { kUnenforcedKAnon, kEnforcedKAnon, kBothKAnonModes }; @@ -726,6 +726,17 @@ static absl::optional<GURL> GetDirectFromSellerSellerSignals( const SubresourceUrlBuilder* subresource_url_builder); + // Replaces `${}` placeholders in a debug report URL's query string for post + // auction signals if exist. Only replaces unescaped placeholder ${}, but + // not escaped placeholder (i.e., %24%7B%7D). + static GURL FillPostAuctionSignals( + const GURL& url, + const PostAuctionSignals& signals, + const absl::optional<PostAuctionSignals>& top_level_signals = + absl::nullopt, + const absl::optional<auction_worklet::mojom::RejectReason> reject_reason = + absl::nullopt); + private: // Note: this needs to be a type with iterator stability, since we both pass // iterators around and remove things from here. @@ -949,17 +960,6 @@ // Computes a key for a worklet associated with `bid_state` AuctionWorkletManager::WorkletKey BidderWorkletKey(BidState& bid_state); - // Replaces `${}` placeholders in a debug report URL's query string for post - // auction signals if exist. Only replaces unescaped placeholder ${}, but - // not escaped placeholder (i.e., %24%7B%7D). - static GURL FillPostAuctionSignals( - const GURL& url, - const PostAuctionSignals& signals, - const absl::optional<PostAuctionSignals>& top_level_signals = - absl::nullopt, - const absl::optional<auction_worklet::mojom::RejectReason> reject_reason = - absl::nullopt); - // Determines if an extended private aggregation buyers request should be // made, and if so, issues the request. Otherwise, does nothing. //
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 80b9dd6ca..45c4932 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -1544,8 +1544,13 @@ if (expected_url.SchemeIs(url::kHttpsScheme)) { WaitForUrl(expected_url); } else { - // The only other URLs this should be used with are about:blank URLs. - ASSERT_EQ(GURL(url::kAboutBlankURL), expected_url); + // The only other URLs this should be used with are about:blank URLs or + // loopback http URLs. + if (expected_url.SchemeIs(url::kHttpScheme)) { + EXPECT_EQ("127.0.0.1", expected_url.host()); + } else { + ASSERT_EQ(GURL(url::kAboutBlankURL), expected_url); + } } // Wait for the load to complete. @@ -1980,6 +1985,26 @@ testing::UnorderedElementsAreArray(expected_groups)); } +// Can't join or leave interest groups from http://localhost, even though it's +// a "secure context" (since it's potentially trustworthy). +IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, CantJoinLeaveHttpLocalhost) { + GURL test_url = embedded_test_server()->GetURL("/echo"); + ASSERT_TRUE(test_url.SchemeIs(url::kHttpScheme)); + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + + EXPECT_EQ( + "SecurityError: Failed to execute 'joinAdInterestGroup' on 'Navigator': " + "May only joinAdInterestGroup from an https origin.", + JoinInterestGroup(url::Origin::Create(GURL("https://example.org/")), + "cars")); + + EXPECT_EQ( + "SecurityError: Failed to execute 'leaveAdInterestGroup' on 'Navigator': " + "May only leaveAdInterestGroup from an https origin.", + LeaveInterestGroup(url::Origin::Create(GURL("https://example.org/")), + "cars")); +} + // Test the case of a cross-origin iframe joining and leaving same-origin // interest groups. This should succeed without any .well-known fetches needed. IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, @@ -7520,6 +7545,36 @@ } } +// Can't do zero-argument leave of interest groups from http://localhost, even +// though it's a "secure context" (since it's potentially trustworthy). +IN_PROC_BROWSER_TEST_F(InterestGroupFencedFrameBrowserTest, + CantLeaveZeroArgHttpLocalhost) { + GURL test_url = embedded_test_server()->GetURL("/fenced_frames/basic.html"); + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + + GURL resource_url = embedded_test_server()->GetURL( + "/set-header?Supports-Loading-Mode: fenced-frame"); + + // This is to get the raw exception string rather than the nicer + // (but more complicated) error message. + const char kLeaveScript[] = R"( + (async function() { + try { + await navigator.leaveAdInterestGroup(); + return "success"; + } catch (e) { + return e.toString(); + } + })() + )"; + + NavigateFencedFrameAndWait(resource_url, resource_url, shell()); + EXPECT_EQ( + "SecurityError: Failed to execute 'leaveAdInterestGroup' on 'Navigator': " + "May only leaveAdInterestGroup from an https origin.", + EvalJs(GetFencedFrameRenderFrameHost(shell()), kLeaveScript)); +} + // Runs auction just like test InterestGroupBrowserTest.RunAdAuctionWithWinner, // but runs with fenced frames enabled and expects to receive a URN URL to be // used. After the auction, loads the URL in a fenced frame, and expects the
diff --git a/content/browser/media/flinging_renderer.cc b/content/browser/media/flinging_renderer.cc index 1aae86a..ab10996 100644 --- a/content/browser/media/flinging_renderer.cc +++ b/content/browser/media/flinging_renderer.cc
@@ -100,10 +100,10 @@ void FlingingRenderer::SetPlaybackRate(double playback_rate) { DVLOG(2) << __func__; if (playback_rate == 0) { - SetExpectedPlayState(PlayState::PAUSED); + SetExpectedPlayState(PlayState::kPaused); controller_->GetMediaController()->Pause(); } else { - SetExpectedPlayState(PlayState::PLAYING); + SetExpectedPlayState(PlayState::kPlaying); controller_->GetMediaController()->Play(); } } @@ -123,7 +123,7 @@ void FlingingRenderer::SetExpectedPlayState(PlayState state) { DVLOG(3) << __func__ << " : state " << static_cast<int>(state); - DCHECK(state == PlayState::PLAYING || state == PlayState::PAUSED); + DCHECK(state == PlayState::kPlaying || state == PlayState::kPaused); expected_play_state_ = state; play_state_is_stable_ = (expected_play_state_ == last_play_state_received_); @@ -153,8 +153,8 @@ // UNKNOWN and BUFFERING states are uninteresting and can be safely ignored. // STOPPED normally causes the session to teardown, and |this| is destroyed // shortly after. - if (current_state != PlayState::PLAYING && - current_state != PlayState::PAUSED) { + if (current_state != PlayState::kPlaying && + current_state != PlayState::kPaused) { DVLOG(3) << __func__ << " : external state ignored: " << static_cast<int>(current_state); return;
diff --git a/content/browser/media/flinging_renderer.h b/content/browser/media/flinging_renderer.h index 722a010..b4f8b200 100644 --- a/content/browser/media/flinging_renderer.h +++ b/content/browser/media/flinging_renderer.h
@@ -74,7 +74,7 @@ // The play state that we expect the remote device to reach. // Updated whenever WMPI sends play/pause commands. - PlayState expected_play_state_ = PlayState::UNKNOWN; + PlayState expected_play_state_ = PlayState::kUnknown; // True when the remote device has reached the expected play state. // False when it is transitioning. @@ -82,7 +82,7 @@ // The last "stable" play state received from the cast device. // Only updated when |play_state_is_stable_| is true. - PlayState last_play_state_received_ = PlayState::UNKNOWN; + PlayState last_play_state_received_ = PlayState::kUnknown; raw_ptr<media::RendererClient> client_;
diff --git a/content/browser/network/shared_dictionary_browsertest.cc b/content/browser/network/shared_dictionary_browsertest.cc index 8ee2c79..1fb4a5f 100644 --- a/content/browser/network/shared_dictionary_browsertest.cc +++ b/content/browser/network/shared_dictionary_browsertest.cc
@@ -1970,6 +1970,7 @@ }, base::Unretained( GetTargetShell()->web_contents()->GetBrowserContext())), + /*storage_partition_config=*/absl::nullopt, /*origin=*/url::Origin::Create(GetURL("/")), content::ClearSiteDataTypeSet::All(), /*storage_buckets_to_remove=*/{},
diff --git a/content/browser/renderer_host/browsing_context_state.cc b/content/browser/renderer_host/browsing_context_state.cc index 33704e35..81e1569 100644 --- a/content/browser/renderer_host/browsing_context_state.cc +++ b/content/browser/renderer_host/browsing_context_state.cc
@@ -50,6 +50,7 @@ BrowsingContextState::~BrowsingContextState() { TRACE_EVENT_END("navigation", perfetto::Track::FromPointer(this)); + CHECK(proxy_hosts_.empty()); } RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHost(
diff --git a/content/browser/renderer_host/frame_navigation_entry.cc b/content/browser/renderer_host/frame_navigation_entry.cc index 1acf4881..e3086bf 100644 --- a/content/browser/renderer_host/frame_navigation_entry.cc +++ b/content/browser/renderer_host/frame_navigation_entry.cc
@@ -93,6 +93,8 @@ item_sequence_number_ = item_sequence_number; document_sequence_number_ = document_sequence_number; navigation_api_key_ = navigation_api_key; + // TODO(nasko, creis): The SiteInstance of a FrameNavigationEntry should + // not change once it has been assigned. See https://crbug.com/849430. site_instance_ = site_instance; source_site_instance_ = std::move(source_site_instance); redirect_chain_ = redirect_chain;
diff --git a/content/browser/renderer_host/frame_navigation_entry.h b/content/browser/renderer_host/frame_navigation_entry.h index fd83fe1..3eb8dec 100644 --- a/content/browser/renderer_host/frame_navigation_entry.h +++ b/content/browser/renderer_host/frame_navigation_entry.h
@@ -122,12 +122,6 @@ // process. This is a refcounted pointer that keeps the SiteInstance (not // necessarily the process) alive as long as this object remains in the // session history. - // TODO(nasko, creis): The SiteInstance of a FrameNavigationEntry should - // not change once it has been assigned. See https://crbug.com/849430. - void set_site_instance(scoped_refptr<SiteInstanceImpl> site_instance) { - CHECK(!site_instance_ || site_instance_ == site_instance); - site_instance_ = std::move(site_instance); - } SiteInstanceImpl* site_instance() const { return site_instance_.get(); } // The |source_site_instance| is used to identify the SiteInstance of the @@ -256,6 +250,8 @@ int64_t document_sequence_number_; std::string navigation_api_key_; + // TODO(nasko, creis): The SiteInstance of a FrameNavigationEntry should + // not change once it has been assigned. See https://crbug.com/849430. scoped_refptr<SiteInstanceImpl> site_instance_; // This member is cleared at commit time and is not persisted. scoped_refptr<SiteInstanceImpl> source_site_instance_;
diff --git a/content/browser/renderer_host/navigation_entry_impl.cc b/content/browser/renderer_host/navigation_entry_impl.cc index d74f642..1c318ac 100644 --- a/content/browser/renderer_host/navigation_entry_impl.cc +++ b/content/browser/renderer_host/navigation_entry_impl.cc
@@ -559,12 +559,6 @@ return blink::PageState::CreateFromEncodedData(encoded_data); } -void NavigationEntryImpl::set_site_instance( - scoped_refptr<SiteInstanceImpl> site_instance) { - // TODO(creis): Update all callers and remove this method. - frame_tree_->frame_entry->set_site_instance(std::move(site_instance)); -} - const std::u16string& NavigationEntryImpl::GetTitleForDisplay() { // Most pages have real titles. Don't even bother caching anything if this is // the case.
diff --git a/content/browser/renderer_host/navigation_entry_impl.h b/content/browser/renderer_host/navigation_entry_impl.h index 896acb6..e48b6870 100644 --- a/content/browser/renderer_host/navigation_entry_impl.h +++ b/content/browser/renderer_host/navigation_entry_impl.h
@@ -332,7 +332,6 @@ // Note that the SiteInstance should usually not be changed after it is set, // but this may happen if the NavigationEntry was cloned and needs to use a // different SiteInstance. - void set_site_instance(scoped_refptr<SiteInstanceImpl> site_instance); SiteInstanceImpl* site_instance() const { return frame_tree_->frame_entry->site_instance(); }
diff --git a/content/browser/renderer_host/navigation_entry_impl_unittest.cc b/content/browser/renderer_host/navigation_entry_impl_unittest.cc index da39c5a..d67216d 100644 --- a/content/browser/renderer_host/navigation_entry_impl_unittest.cc +++ b/content/browser/renderer_host/navigation_entry_impl_unittest.cc
@@ -186,10 +186,8 @@ // Test other basic accessors TEST_F(NavigationEntryTest, NavigationEntryAccessors) { // SiteInstance - EXPECT_TRUE(entry1_->site_instance() == nullptr); + EXPECT_EQ(nullptr, entry1_->site_instance()); EXPECT_EQ(instance_, entry2_->site_instance()); - entry1_->set_site_instance(instance_); - EXPECT_EQ(instance_, entry1_->site_instance()); // Page type EXPECT_EQ(PAGE_TYPE_NORMAL, entry1_->GetPageType());
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc index 9936a46..80a8f57 100644 --- a/content/browser/site_instance_impl_unittest.cc +++ b/content/browser/site_instance_impl_unittest.cc
@@ -483,23 +483,23 @@ SiteInstanceDestructionObserver observer(instance.get()); EXPECT_FALSE(observer.site_instance_deleted()); - NavigationEntryImpl* e1 = new NavigationEntryImpl( - instance, url, Referrer(), /* initiator_origin= */ absl::nullopt, - /* initiator_base_url= */ absl::nullopt, std::u16string(), - ui::PAGE_TRANSITION_LINK, false, nullptr /* blob_url_loader_factory */, - false /* is_initial_entry */); + std::unique_ptr<NavigationEntryImpl> e1 = + std::make_unique<NavigationEntryImpl>( + instance, url, Referrer(), /* initiator_origin= */ absl::nullopt, + /* initiator_base_url= */ absl::nullopt, std::u16string(), + ui::PAGE_TRANSITION_LINK, false, + nullptr /* blob_url_loader_factory */, false /* is_initial_entry */); - // Redundantly setting e1's SiteInstance shouldn't affect the ref count. - e1->set_site_instance(instance); EXPECT_FALSE(observer.site_instance_deleted()); EXPECT_FALSE(observer.browsing_instance_deleted()); // Add a second reference - NavigationEntryImpl* e2 = new NavigationEntryImpl( - instance, url, Referrer(), /* initiator_origin= */ absl::nullopt, - /* initiator_base_url= */ absl::nullopt, std::u16string(), - ui::PAGE_TRANSITION_LINK, false, nullptr /* blob_url_loader_factory */, - false /* is_initial_entry */); + std::unique_ptr<NavigationEntryImpl> e2 = + std::make_unique<NavigationEntryImpl>( + instance, url, Referrer(), /* initiator_origin= */ absl::nullopt, + /* initiator_base_url= */ absl::nullopt, std::u16string(), + ui::PAGE_TRANSITION_LINK, false, + nullptr /* blob_url_loader_factory */, false /* is_initial_entry */); instance = nullptr; @@ -507,17 +507,18 @@ EXPECT_FALSE(observer.browsing_instance_deleted()); // Now delete both entries and be sure the SiteInstance goes away. - delete e1; + e1.reset(); EXPECT_FALSE(observer.site_instance_deleted()); EXPECT_FALSE(observer.browsing_instance_deleted()); - delete e2; + e2.reset(); // instance is now deleted EXPECT_TRUE(observer.site_instance_deleted()); EXPECT_TRUE(observer.browsing_instance_deleted()); // browsing_instance is now deleted // Ensure that instances are deleted when their RenderFrameHosts are gone. - std::unique_ptr<TestBrowserContext> browser_context(new TestBrowserContext()); + std::unique_ptr<TestBrowserContext> browser_context = + std::make_unique<TestBrowserContext>(); SiteInstanceDestructionObserver observer2; { std::unique_ptr<WebContents> web_contents(
diff --git a/content/browser/theme_helper_mac.mm b/content/browser/theme_helper_mac.mm index 655cda21..e61b9e1 100644 --- a/content/browser/theme_helper_mac.mm +++ b/content/browser/theme_helper_mac.mm
@@ -14,14 +14,12 @@ #include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" #include "content/browser/renderer_host/render_process_host_impl.h" -#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/renderer.mojom.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" @@ -236,14 +234,9 @@ std::move(params)); } - std::unique_ptr<content::RenderWidgetHostIterator> all_widgets( - content::RenderWidgetHostImpl::GetAllRenderWidgetHosts()); - while (content::RenderWidgetHost* widget = all_widgets->GetNextHost()) { - content::RenderViewHost* rvh = content::RenderViewHost::From(widget); - if (!rvh) - continue; - - content::WebContents::FromRenderViewHost(rvh)->OnWebPreferencesChanged(); + for (content::WebContentsImpl* web_contents : + content::WebContentsImpl::GetAllWebContents()) { + web_contents->OnWebPreferencesChanged(); } }
diff --git a/content/public/browser/clear_site_data_utils.h b/content/public/browser/clear_site_data_utils.h index 7d6e697..7f547a5 100644 --- a/content/public/browser/clear_site_data_utils.h +++ b/content/public/browser/clear_site_data_utils.h
@@ -8,6 +8,7 @@ #include "base/containers/enum_set.h" #include "base/functional/callback_forward.h" #include "content/common/content_export.h" +#include "content/public/browser/storage_partition_config.h" #include "net/cookies/cookie_partition_key.h" #include "third_party/blink/public/common/storage_key/storage_key.h" @@ -35,12 +36,13 @@ // thread when done. CONTENT_EXPORT void ClearSiteData( const base::RepeatingCallback<BrowserContext*()>& browser_context_getter, + const absl::optional<StoragePartitionConfig> storage_partition_config, const url::Origin& origin, const ClearSiteDataTypeSet clear_site_data_types, const std::set<std::string>& storage_buckets_to_remove, bool avoid_closing_connections, - const absl::optional<net::CookiePartitionKey>& cookie_partition_key, - const absl::optional<blink::StorageKey>& storage_key, + const absl::optional<net::CookiePartitionKey> cookie_partition_key, + const absl::optional<blink::StorageKey> storage_key, bool partitioned_state_allowed_only, base::OnceClosure callback);
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index a8ec2da..7f28184e 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1827,6 +1827,15 @@ return visited_frames; } +std::vector<WebContents*> GetAllWebContents() { + std::vector<WebContentsImpl*> all_wci = WebContentsImpl::GetAllWebContents(); + std::vector<WebContents*> all_wc; + std::transform(all_wci.cbegin(), all_wci.cend(), std::back_inserter(all_wc), + [](WebContentsImpl* wc) { return wc; }); + + return all_wc; +} + #if BUILDFLAG(IS_CHROMEOS_ASH) bool ExecuteWebUIResourceTest(WebContents* web_contents) { // Inject WebUI test runner script.
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 4696c660a..b899d18 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -914,6 +914,10 @@ std::vector<RenderFrameHost*> CollectAllRenderFrameHosts( WebContents* web_contents); +// Returns all WebContents. Note that this includes WebContents from any +// BrowserContext. +std::vector<WebContents*> GetAllWebContents(); + #if BUILDFLAG(IS_CHROMEOS_ASH) // Executes the WebUI resource tests. Injects the test runner script prior to // executing the tests.
diff --git a/content/services/auction_worklet/set_bid_bindings.cc b/content/services/auction_worklet/set_bid_bindings.cc index 5a653cb9..211d766 100644 --- a/content/services/auction_worklet/set_bid_bindings.cc +++ b/content/services/auction_worklet/set_bid_bindings.cc
@@ -415,7 +415,8 @@ bid_ = mojom::BidderWorkletBid::New( std::move(ad_json), *idl.bid, std::move(bid_currency), std::move(idl.ad_cost), blink::AdDescriptor(render_url, render_size), - std::move(ad_component_descriptors), std::move(modeling_signals), + std::move(ad_component_descriptors), + static_cast<absl::optional<uint16_t>>(modeling_signals), /*bid_duration=*/base::TimeDelta()); return IdlConvert::Status::MakeSuccess(); }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 38ff27b6..ee9bc2a 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2395,6 +2395,7 @@ "../browser/indexed_db/mock_mojo_indexed_db_factory_client.h", "../browser/interest_group/ad_auction_service_impl_unittest.cc", "../browser/interest_group/ad_auction_url_loader_interceptor_unittest.cc", + "../browser/interest_group/additional_bids_util_unittest.cc", "../browser/interest_group/auction_metrics_recorder_unittest.cc", "../browser/interest_group/auction_nonce_manager_unittest.cc", "../browser/interest_group/auction_process_manager_unittest.cc",
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 0df7f3c..da83273a 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -501,6 +501,7 @@ crbug.com/772651 [ mac nvidia ] conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html [ Failure ] crbug.com/795052 [ mac nvidia-0xfe9 ] conformance2/uniforms/draw-with-uniform-blocks.html [ Failure ] crbug.com/1457723 [ bigsur nvidia-0xfe9 angle-opengl ] conformance2/textures/canvas_sub_rectangle/tex-3d-* [ Failure ] +crbug.com/1474910 [ bigsur nvidia-0xfe9 angle-opengl ] conformance2/rendering/vertex-id-large-count.html [ Failure ] ## Mac AMD ##
diff --git a/extensions/browser/api/networking_private/networking_private_delegate_factory.cc b/extensions/browser/api/networking_private/networking_private_delegate_factory.cc index b4fbc80..fab58cf8 100644 --- a/extensions/browser/api/networking_private/networking_private_delegate_factory.cc +++ b/extensions/browser/api/networking_private/networking_private_delegate_factory.cc
@@ -57,20 +57,22 @@ ui_factory_ = std::move(factory); } -KeyedService* NetworkingPrivateDelegateFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +NetworkingPrivateDelegateFactory::BuildServiceInstanceForBrowserContext( BrowserContext* browser_context) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - NetworkingPrivateDelegate* delegate; + std::unique_ptr<NetworkingPrivateDelegate> delegate; #if BUILDFLAG(IS_CHROMEOS_ASH) - delegate = new NetworkingPrivateChromeOS(browser_context); + delegate = std::make_unique<NetworkingPrivateChromeOS>(browser_context); #elif BUILDFLAG(IS_CHROMEOS_LACROS) - delegate = new NetworkingPrivateLacros(browser_context); + delegate = std::make_unique<NetworkingPrivateLacros>(browser_context); #elif BUILDFLAG(IS_LINUX) - delegate = new NetworkingPrivateLinux(); + delegate = std::make_unique<NetworkingPrivateLinux>(); #elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) std::unique_ptr<wifi::WiFiService> wifi_service(wifi::WiFiService::Create()); - delegate = new NetworkingPrivateServiceClient(std::move(wifi_service)); + delegate = + std::make_unique<NetworkingPrivateServiceClient>(std::move(wifi_service)); #else NOTREACHED(); delegate = nullptr;
diff --git a/extensions/browser/api/networking_private/networking_private_delegate_factory.h b/extensions/browser/api/networking_private/networking_private_delegate_factory.h index 6ef4ccb1..d6bfdce 100644 --- a/extensions/browser/api/networking_private/networking_private_delegate_factory.h +++ b/extensions/browser/api/networking_private/networking_private_delegate_factory.h
@@ -58,7 +58,7 @@ ~NetworkingPrivateDelegateFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* browser_context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/browser/api/networking_private/networking_private_linux.h b/extensions/browser/api/networking_private/networking_private_linux.h index 8c6d667..792442d 100644 --- a/extensions/browser/api/networking_private/networking_private_linux.h +++ b/extensions/browser/api/networking_private/networking_private_linux.h
@@ -34,6 +34,7 @@ typedef std::vector<std::string> GuidList; NetworkingPrivateLinux(); + ~NetworkingPrivateLinux() override; NetworkingPrivateLinux(const NetworkingPrivateLinux&) = delete; NetworkingPrivateLinux& operator=(const NetworkingPrivateLinux&) = delete; @@ -102,7 +103,6 @@ void RemoveObserver(NetworkingPrivateDelegateObserver* observer) override; private: - ~NetworkingPrivateLinux() override; // https://developer.gnome.org/NetworkManager/unstable/spec.html#type-NM_DEVICE_TYPE enum DeviceType {
diff --git a/extensions/browser/api/networking_private/networking_private_service_client.h b/extensions/browser/api/networking_private/networking_private_service_client.h index 81678335..570be29c 100644 --- a/extensions/browser/api/networking_private/networking_private_service_client.h +++ b/extensions/browser/api/networking_private/networking_private_service_client.h
@@ -37,6 +37,7 @@ // worker thread. The deletion task is posted from the destructor. explicit NetworkingPrivateServiceClient( std::unique_ptr<wifi::WiFiService> wifi_service); + ~NetworkingPrivateServiceClient() override; NetworkingPrivateServiceClient(const NetworkingPrivateServiceClient&) = delete; @@ -133,8 +134,6 @@ }; using ServiceCallbacksMap = base::IDMap<std::unique_ptr<ServiceCallbacks>>; - ~NetworkingPrivateServiceClient() override; - // Callback wrappers. void AfterGetProperties(PropertiesCallback callback, const std::string& network_guid,
diff --git a/extensions/browser/api/user_scripts/user_scripts_api.cc b/extensions/browser/api/user_scripts/user_scripts_api.cc index bc91d39..a9a2b20 100644 --- a/extensions/browser/api/user_scripts/user_scripts_api.cc +++ b/extensions/browser/api/user_scripts/user_scripts_api.cc
@@ -97,6 +97,45 @@ return result; } +// Converts a UserScript object to a api::user_scripts::RegisteredUserScript +// object, used for getScripts. +api::user_scripts::RegisteredUserScript CreateRegisteredUserScriptInfo( + const UserScript& script) { + api::user_scripts::RegisteredUserScript script_info; + CHECK_EQ(UserScript::Source::kDynamicUserScript, script.GetSource()); + + script_info.id = script.id(); + script_info.all_frames = script.match_all_frames(); + script_info.run_at = ConvertRunLocationForAPI(script.run_location()); + + script_info.matches.emplace(); + script_info.matches->reserve(script.url_patterns().size()); + for (const URLPattern& pattern : script.url_patterns()) { + script_info.matches->push_back(pattern.GetAsString()); + } + + if (!script.exclude_url_patterns().is_empty()) { + script_info.exclude_matches.emplace(); + script_info.exclude_matches->reserve(script.exclude_url_patterns().size()); + for (const URLPattern& pattern : script.exclude_url_patterns()) { + script_info.exclude_matches->push_back(pattern.GetAsString()); + } + } + + // File paths may be normalized in the returned object and can differ slightly + // compared to what was originally passed into userScripts.register. + if (!script.js_scripts().empty()) { + script_info.js.reserve(script.js_scripts().size()); + for (const auto& file : script.js_scripts()) { + api::user_scripts::ScriptSource source; + source.file = file->relative_path().AsUTF8Unsafe(); + script_info.js.push_back(std::move(source)); + } + } + + return script_info; +} + } // namespace ExtensionFunction::ResponseAction UserScriptsRegisterFunction::Run() { @@ -202,4 +241,45 @@ Release(); // Matches the `AddRef()` in `Run()`. } +ExtensionFunction::ResponseAction UserScriptsGetScriptsFunction::Run() { + absl::optional<api::user_scripts::GetScripts::Params> params = + api::user_scripts::GetScripts::Params::Create(args()); + EXTENSION_FUNCTION_VALIDATE(params); + + absl::optional<api::user_scripts::UserScriptFilter>& filter = params->filter; + std::set<std::string> id_filter; + if (filter && filter->ids) { + id_filter.insert(std::make_move_iterator(filter->ids->begin()), + std::make_move_iterator(filter->ids->end())); + } + + ExtensionUserScriptLoader* loader = + ExtensionSystem::Get(browser_context()) + ->user_script_manager() + ->GetUserScriptLoaderForExtension(extension()->id()); + const UserScriptList& dynamic_scripts = loader->GetLoadedDynamicScripts(); + + std::vector<api::user_scripts::RegisteredUserScript> registered_user_scripts; + for (const std::unique_ptr<UserScript>& script : dynamic_scripts) { + if (script->GetSource() != UserScript::Source::kDynamicUserScript) { + continue; + } + + std::string id_without_prefix = script->GetIDWithoutPrefix(); + if (filter && filter->ids && + !base::Contains(id_filter, id_without_prefix)) { + continue; + } + + auto user_script = CreateRegisteredUserScriptInfo(*script); + // Remove the internally used prefix from the `script`'s ID before + // returning. + user_script.id = id_without_prefix; + registered_user_scripts.push_back(std::move(user_script)); + } + + return RespondNow(ArgumentList( + api::user_scripts::GetScripts::Results::Create(registered_user_scripts))); +} + } // namespace extensions
diff --git a/extensions/browser/api/user_scripts/user_scripts_api.h b/extensions/browser/api/user_scripts/user_scripts_api.h index 0ed1235..d9a1574 100644 --- a/extensions/browser/api/user_scripts/user_scripts_api.h +++ b/extensions/browser/api/user_scripts/user_scripts_api.h
@@ -33,6 +33,22 @@ void OnUserScriptsRegistered(const absl::optional<std::string>& error); }; +class UserScriptsGetScriptsFunction : public ExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("userScripts.getScripts", USERSCRIPTS_GETSCRIPTS) + + UserScriptsGetScriptsFunction() = default; + UserScriptsGetScriptsFunction(const UserScriptsRegisterFunction&) = delete; + const UserScriptsGetScriptsFunction& operator=( + const UserScriptsGetScriptsFunction&) = delete; + + // ExtensionFunction: + ResponseAction Run() override; + + private: + ~UserScriptsGetScriptsFunction() override = default; +}; + } // namespace extensions #endif // EXTENSIONS_BROWSER_API_USER_SCRIPTS_USER_SCRIPTS_API_H_
diff --git a/extensions/browser/app_window/app_window_geometry_cache.cc b/extensions/browser/app_window/app_window_geometry_cache.cc index a8aaed4..c6b5197 100644 --- a/extensions/browser/app_window/app_window_geometry_cache.cc +++ b/extensions/browser/app_window/app_window_geometry_cache.cc
@@ -269,9 +269,11 @@ AppWindowGeometryCache::Factory::~Factory() = default; -KeyedService* AppWindowGeometryCache::Factory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AppWindowGeometryCache::Factory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new AppWindowGeometryCache(context, ExtensionPrefs::Get(context)); + return std::make_unique<AppWindowGeometryCache>(context, + ExtensionPrefs::Get(context)); } content::BrowserContext*
diff --git a/extensions/browser/app_window/app_window_geometry_cache.h b/extensions/browser/app_window/app_window_geometry_cache.h index f5ed0cbe..857fd1f8 100644 --- a/extensions/browser/app_window/app_window_geometry_cache.h +++ b/extensions/browser/app_window/app_window_geometry_cache.h
@@ -50,7 +50,7 @@ ~Factory() override; // BrowserContextKeyedServiceFactory - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/browser/app_window/app_window_registry.cc b/extensions/browser/app_window/app_window_registry.cc index ba74f07..538c2a96 100644 --- a/extensions/browser/app_window/app_window_registry.cc +++ b/extensions/browser/app_window/app_window_registry.cc
@@ -233,9 +233,10 @@ AppWindowRegistry::Factory::~Factory() = default; -KeyedService* AppWindowRegistry::Factory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +AppWindowRegistry::Factory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new AppWindowRegistry(context); + return std::make_unique<AppWindowRegistry>(context); } bool AppWindowRegistry::Factory::ServiceIsCreatedWithBrowserContext() const {
diff --git a/extensions/browser/app_window/app_window_registry.h b/extensions/browser/app_window/app_window_registry.h index 2e69f718..5bac2fa6 100644 --- a/extensions/browser/app_window/app_window_registry.h +++ b/extensions/browser/app_window/app_window_registry.h
@@ -116,7 +116,7 @@ ~Factory() override; // BrowserContextKeyedServiceFactory - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; content::BrowserContext* GetBrowserContextToUse(
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 5b39820..e0c2c9a 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1880,6 +1880,8 @@ OS_DIAGNOSTICS_RUNBLUETOOTHSCANNINGROUTINE = 1818, OS_DIAGNOSTICS_RUNBLUETOOTHPAIRINGROUTINE = 1819, FILEMANAGERPRIVATE_DISMISSIOTASK = 1820, + ACCESSIBILITY_PRIVATE_SHOWTOAST = 1821, + USERSCRIPTS_GETSCRIPTS = 1822, // Last entry: Add new entries above, then run: // tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/extension_registry_factory.cc b/extensions/browser/extension_registry_factory.cc index f7ad1e40..719617a4 100644 --- a/extensions/browser/extension_registry_factory.cc +++ b/extensions/browser/extension_registry_factory.cc
@@ -34,9 +34,10 @@ ExtensionRegistryFactory::~ExtensionRegistryFactory() = default; -KeyedService* ExtensionRegistryFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ExtensionRegistryFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return new ExtensionRegistry(context); + return std::make_unique<ExtensionRegistry>(context); } BrowserContext* ExtensionRegistryFactory::GetBrowserContextToUse(
diff --git a/extensions/browser/extension_registry_factory.h b/extensions/browser/extension_registry_factory.h index 0acb40f..08735569 100644 --- a/extensions/browser/extension_registry_factory.h +++ b/extensions/browser/extension_registry_factory.h
@@ -32,7 +32,7 @@ ~ExtensionRegistryFactory() override; // BrowserContextKeyedServiceFactory implementation: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/browser/process_map_factory.cc b/extensions/browser/process_map_factory.cc index f185cd4..da42c9e5 100644 --- a/extensions/browser/process_map_factory.cc +++ b/extensions/browser/process_map_factory.cc
@@ -32,9 +32,10 @@ ProcessMapFactory::~ProcessMapFactory() = default; -KeyedService* ProcessMapFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ProcessMapFactory::BuildServiceInstanceForBrowserContext( BrowserContext* context) const { - ProcessMap* process_map = new ProcessMap(); + std::unique_ptr<ProcessMap> process_map = std::make_unique<ProcessMap>(); process_map->set_is_lock_screen_context( ExtensionsBrowserClient::Get()->IsLockScreenContext(context)); return process_map;
diff --git a/extensions/browser/process_map_factory.h b/extensions/browser/process_map_factory.h index 9401052..23e39bf 100644 --- a/extensions/browser/process_map_factory.h +++ b/extensions/browser/process_map_factory.h
@@ -31,7 +31,7 @@ ~ProcessMapFactory() override; // BrowserContextKeyedServiceFactory implementation: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/browser/service_worker_task_queue_factory.cc b/extensions/browser/service_worker_task_queue_factory.cc index 929bdcc..e7f4a7a 100644 --- a/extensions/browser/service_worker_task_queue_factory.cc +++ b/extensions/browser/service_worker_task_queue_factory.cc
@@ -35,9 +35,10 @@ ServiceWorkerTaskQueueFactory::~ServiceWorkerTaskQueueFactory() = default; -KeyedService* ServiceWorkerTaskQueueFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +ServiceWorkerTaskQueueFactory::BuildServiceInstanceForBrowserContext( BrowserContext* context) const { - ServiceWorkerTaskQueue* task_queue = new ServiceWorkerTaskQueue(context); + auto task_queue = std::make_unique<ServiceWorkerTaskQueue>(context); BrowserContext* original_context = ExtensionsBrowserClient::Get()->GetContextRedirectedToOriginal( context, /*force_guest_profile=*/true);
diff --git a/extensions/browser/service_worker_task_queue_factory.h b/extensions/browser/service_worker_task_queue_factory.h index 95264ab..e74f14d 100644 --- a/extensions/browser/service_worker_task_queue_factory.h +++ b/extensions/browser/service_worker_task_queue_factory.h
@@ -29,7 +29,7 @@ ~ServiceWorkerTaskQueueFactory() override; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/extensions/common/api/user_scripts.idl b/extensions/common/api/user_scripts.idl index aa00703..ee7a0b63a 100644 --- a/extensions/common/api/user_scripts.idl +++ b/extensions/common/api/user_scripts.idl
@@ -45,8 +45,17 @@ extensionTypes.RunAt? runAt; }; + // An object used to filter user scripts for ${ref:getScripts}. + dictionary UserScriptFilter { + // $(ref:getScripts) only returns scripts with the IDs specified in this + // list. + DOMString[]? ids; + }; + callback RegisterCallback = void(); + callback GetScriptsCallback = void(RegisteredUserScript[] scripts); + interface Functions { // Registers one or more user scripts for this extension. // |scripts|: Contains a list of user scripts to be registered. @@ -54,5 +63,14 @@ // has ocurred. [supportsPromises] static void register(RegisteredUserScript[] scripts, optional RegisterCallback callback); + + // Returns all dynamically-registered user scripts for this extension. + // |filter|: If filter is specified, this method returns only the scripts + // that match it. + // |callback|: Called once scripts have been fully registered or if an error + // occurs. + [supportsPromises] static void getScripts( + optional UserScriptFilter filter, + GetScriptsCallback callback); }; };
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index 73b692b..4cd56d0 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -1158,6 +1158,7 @@ case wgpu::FeatureName::TimestampQueryInsidePasses: case wgpu::FeatureName::PipelineStatisticsQuery: case wgpu::FeatureName::ChromiumExperimentalDp4a: + case wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture: // TODO(dawn:1664): Enable Float32Filterable by default once it is tested. case wgpu::FeatureName::Float32Filterable: case wgpu::FeatureName::ShaderF16:
diff --git a/infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/properties.json b/infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/properties.json new file mode 100644 index 0000000..d309f946 --- /dev/null +++ b/infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/properties.json
@@ -0,0 +1,68 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "android-chrome-pie-x86-wpt-android-specific", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-android-archive", + "builder_group": "chromium.android.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "x86_builder" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "android", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "android-chrome-pie-x86-wpt-android-specific", + "project": "chromium" + } + ], + "mirroring_builder_group_and_names": [ + { + "builder": "android-chrome-pie-x86-wpt-android-specific", + "group": "tryserver.chromium.android" + } + ] + } + }, + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.android.fyi", + "recipe": "chromium" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/shadow-properties.json b/infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/shadow-properties.json new file mode 100644 index 0000000..999510c --- /dev/null +++ b/infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/shadow-properties.json
@@ -0,0 +1,8 @@ +{ + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + } +} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json b/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json index da584d79..91ad62d 100644 --- a/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json +++ b/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json
@@ -60,5 +60,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-device/properties.json b/infra/config/generated/builders/ci/ios-device/properties.json index a6dbcbc..ea9975e0 100644 --- a/infra/config/generated/builders/ci/ios-device/properties.json +++ b/infra/config/generated/builders/ci/ios-device/properties.json
@@ -64,5 +64,5 @@ "chromium", "ios" ], - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json b/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json index 1b404db7..99653bc4 100644 --- a/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json +++ b/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
@@ -59,5 +59,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json b/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json index bafe0f8..3847dec 100644 --- a/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json +++ b/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
@@ -59,5 +59,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-m1-simulator/properties.json b/infra/config/generated/builders/ci/ios-m1-simulator/properties.json index b710583..b0a640ac 100644 --- a/infra/config/generated/builders/ci/ios-m1-simulator/properties.json +++ b/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
@@ -59,5 +59,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json b/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json index a6fc1c5..3135d64 100644 --- a/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json +++ b/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
@@ -72,5 +72,5 @@ }, "builder_group": "chromium.coverage", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json b/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json index a18151d..a599567 100644 --- a/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json +++ b/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
@@ -60,5 +60,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json b/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json index d55a91c..88571ec 100644 --- a/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json +++ b/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
@@ -67,5 +67,5 @@ "chromium", "ios" ], - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json b/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json index 803a2a6..e0b3e38 100644 --- a/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json +++ b/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
@@ -60,5 +60,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json b/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json index 0368ee0..6eaeac39 100644 --- a/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json +++ b/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
@@ -64,5 +64,5 @@ "chromium", "ios" ], - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator/properties.json b/infra/config/generated/builders/ci/ios-simulator/properties.json index e1e7482..b99856c 100644 --- a/infra/config/generated/builders/ci/ios-simulator/properties.json +++ b/infra/config/generated/builders/ci/ios-simulator/properties.json
@@ -71,5 +71,5 @@ "chromium", "ios" ], - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json b/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json index 02c66da0a..b32402f 100644 --- a/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json +++ b/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json
@@ -59,5 +59,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json b/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json index e7bbb9f..0d145cc0 100644 --- a/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json +++ b/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
@@ -60,5 +60,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json b/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json index 24214ec..d1c592a 100644 --- a/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json +++ b/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json
@@ -60,5 +60,5 @@ }, "builder_group": "chromium.fyi", "recipe": "chromium", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/android-chrome-pie-x86-wpt-android-specific/properties.json b/infra/config/generated/builders/try/android-chrome-pie-x86-wpt-android-specific/properties.json new file mode 100644 index 0000000..78af0a71e --- /dev/null +++ b/infra/config/generated/builders/try/android-chrome-pie-x86-wpt-android-specific/properties.json
@@ -0,0 +1,62 @@ +{ + "$build/chromium_tests_builder_config": { + "builder_config": { + "builder_db": { + "entries": [ + { + "builder_id": { + "bucket": "ci", + "builder": "android-chrome-pie-x86-wpt-android-specific", + "project": "chromium" + }, + "builder_spec": { + "build_gs_bucket": "chromium-android-archive", + "builder_group": "chromium.android.fyi", + "execution_mode": "COMPILE_AND_TEST", + "legacy_android_config": { + "config": "x86_builder" + }, + "legacy_chromium_config": { + "apply_configs": [ + "mb" + ], + "build_config": "Release", + "config": "android", + "target_bits": 32, + "target_platform": "android" + }, + "legacy_gclient_config": { + "apply_configs": [ + "android" + ], + "config": "chromium" + } + } + } + ] + }, + "builder_ids": [ + { + "bucket": "ci", + "builder": "android-chrome-pie-x86-wpt-android-specific", + "project": "chromium" + } + ] + } + }, + "$build/reclient": { + "instance": "rbe-chromium-untrusted", + "jobs": 500, + "metrics_project": "chromium-reclient-metrics", + "scandeps_server": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.android", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-asan/properties.json b/infra/config/generated/builders/try/ios-asan/properties.json index 51f2437..bfa4a88 100644 --- a/infra/config/generated/builders/try/ios-asan/properties.json +++ b/infra/config/generated/builders/try/ios-asan/properties.json
@@ -58,5 +58,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json b/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json index 3b7cd21..9a5fd4e03 100644 --- a/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json +++ b/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json
@@ -53,5 +53,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-device/properties.json b/infra/config/generated/builders/try/ios-device/properties.json index 74343dfb..ba96edf3 100644 --- a/infra/config/generated/builders/try/ios-device/properties.json +++ b/infra/config/generated/builders/try/ios-device/properties.json
@@ -54,5 +54,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json b/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json index 4f0961b..14f9a535 100644 --- a/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json +++ b/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
@@ -52,5 +52,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json b/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json index 596e2f06..1874d22 100644 --- a/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json +++ b/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
@@ -53,5 +53,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-m1-simulator/properties.json b/infra/config/generated/builders/try/ios-m1-simulator/properties.json index ed21f948..1d77a74 100644 --- a/infra/config/generated/builders/try/ios-m1-simulator/properties.json +++ b/infra/config/generated/builders/try/ios-m1-simulator/properties.json
@@ -52,5 +52,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json b/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json index 7222e7f..fa8c954 100644 --- a/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json
@@ -56,5 +56,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-compilator/properties.json b/infra/config/generated/builders/try/ios-simulator-compilator/properties.json index fc5c57a..3db9ff42 100644 --- a/infra/config/generated/builders/try/ios-simulator-compilator/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-compilator/properties.json
@@ -69,5 +69,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium/compilator", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-cronet/properties.json b/infra/config/generated/builders/try/ios-simulator-cronet/properties.json index c9616da9..f88e8a9 100644 --- a/infra/config/generated/builders/try/ios-simulator-cronet/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
@@ -59,5 +59,5 @@ "builder_group": "tryserver.chromium.mac", "cq": "path-based", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json b/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json index b17a726..a00935c 100644 --- a/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
@@ -70,5 +70,5 @@ "builder_group": "tryserver.chromium.mac", "cq": "path-based", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json b/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json index ae6a059..1655f43 100644 --- a/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
@@ -56,5 +56,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json b/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json index 9002bf0..d9307d5 100644 --- a/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
@@ -53,5 +53,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-noncq/properties.json b/infra/config/generated/builders/try/ios-simulator-noncq/properties.json index 218f4bd..cfdd638 100644 --- a/infra/config/generated/builders/try/ios-simulator-noncq/properties.json +++ b/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
@@ -59,5 +59,5 @@ "builder_group": "tryserver.chromium.mac", "cq": "path-based", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json b/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json index 58e863e..a16accc 100644 --- a/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json +++ b/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json
@@ -52,5 +52,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios16-beta-simulator/properties.json b/infra/config/generated/builders/try/ios16-beta-simulator/properties.json index 7132c7e..f894c97 100644 --- a/infra/config/generated/builders/try/ios16-beta-simulator/properties.json +++ b/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
@@ -54,5 +54,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios17-beta-simulator/properties.json b/infra/config/generated/builders/try/ios17-beta-simulator/properties.json index 7ecd236..fd5fcb2 100644 --- a/infra/config/generated/builders/try/ios17-beta-simulator/properties.json +++ b/infra/config/generated/builders/try/ios17-beta-simulator/properties.json
@@ -53,5 +53,5 @@ }, "builder_group": "tryserver.chromium.mac", "recipe": "chromium_trybot", - "xcode_build_version": "15a5209g" + "xcode_build_version": "15a5219j" } \ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 8c2121c..f3212f7 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -566,6 +566,10 @@ } } builders { + name: "chromium/try/android-chrome-pie-x86-wpt-android-specific" + includable_only: true + } + builders { name: "chromium/try/android-chrome-pie-x86-wpt-fyi-rel" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index a97620c..bc38fd4 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -5173,13 +5173,13 @@ ' },' ' "builder_group": "chromium.fyi",' ' "recipe": "reclient_reclient_comparison",' - ' "xcode_build_version": "15a5209g"' + ' "xcode_build_version": "15a5219j"' '}' priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -5284,13 +5284,13 @@ ' },' ' "builder_group": "chromium.fyi",' ' "recipe": "reclient_reclient_comparison",' - ' "xcode_build_version": "15a5209g"' + ' "xcode_build_version": "15a5219j"' '}' priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -28813,6 +28813,99 @@ } } builders { + name: "android-chrome-pie-x86-wpt-android-specific" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "free_space:standard" + dimensions: "os:Ubuntu-22.04" + dimensions: "pool:luci.chromium.ci" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/properties.json",' + ' "shadow_properties_file": "infra/config/generated/builders/ci/android-chrome-pie-x86-wpt-android-specific/shadow-properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.android.fyi",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + priority: 35 + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experimental: YES + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + shadow_builder_adjustments { + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + pool: "luci.chromium.try" + dimensions: "free_space:" + dimensions: "pool:luci.chromium.try" + } + } + builders { name: "android-chrome-pie-x86-wpt-fyi-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -37088,8 +37181,8 @@ priority: 35 execution_timeout_secs: 10800 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37282,8 +37375,8 @@ '}' execution_timeout_secs: 10800 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37375,8 +37468,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37469,8 +37562,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37563,8 +37656,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37660,8 +37753,8 @@ '}' execution_timeout_secs: 10800 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37756,8 +37849,8 @@ priority: 35 execution_timeout_secs: 72000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37848,8 +37941,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -37945,8 +38038,8 @@ '}' execution_timeout_secs: 10800 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -38038,8 +38131,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -38135,8 +38228,8 @@ '}' execution_timeout_secs: 10800 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -38322,8 +38415,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -38416,8 +38509,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -38698,8 +38791,8 @@ priority: 35 execution_timeout_secs: 36000 caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -63777,6 +63870,96 @@ } } builders { + name: "android-chrome-pie-x86-wpt-android-specific" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builderless:1" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-22.04" + dimensions: "pool:luci.chromium.try" + dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-chrome-pie-x86-wpt-android-specific/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.android",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "chromium_swarming.expose_merge_script_failures" + value: 100 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "android-chrome-pie-x86-wpt-fyi-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" @@ -77817,8 +78000,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -77909,8 +78092,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78093,8 +78276,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78185,8 +78368,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78277,8 +78460,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78369,8 +78552,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78556,8 +78739,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78648,8 +78831,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78742,8 +78925,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78835,8 +79018,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -78927,8 +79110,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -79019,8 +79202,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -79112,8 +79295,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -79204,8 +79387,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -79296,8 +79479,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -79480,8 +79663,8 @@ seconds: 120 } caches { - name: "xcode_ios_15a5209g" - path: "xcode_ios_15a5209g.app" + name: "xcode_ios_15a5219j" + path: "xcode_ios_15a5219j.app" } build_numbers: YES service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index d2486fa..8995fa3 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -5447,6 +5447,11 @@ short_name: "13" } builders { + name: "buildbucket/luci.chromium.ci/android-chrome-pie-x86-wpt-android-specific" + category: "wpt|chrome" + short_name: "p-x86" + } + builders { name: "buildbucket/luci.chromium.ci/android-chrome-pie-x86-wpt-fyi-rel" category: "wpt|chrome" short_name: "p-x86" @@ -17361,6 +17366,9 @@ name: "buildbucket/luci.chromium.try/android-binary-size" } builders { + name: "buildbucket/luci.chromium.try/android-chrome-pie-x86-wpt-android-specific" + } + builders { name: "buildbucket/luci.chromium.try/android-chrome-pie-x86-wpt-fyi-rel" } builders { @@ -18713,6 +18721,9 @@ name: "buildbucket/luci.chromium.try/android-binary-size" } builders { + name: "buildbucket/luci.chromium.try/android-chrome-pie-x86-wpt-android-specific" + } + builders { name: "buildbucket/luci.chromium.try/android-chrome-pie-x86-wpt-fyi-rel" } builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index e0b9d90a..d1e1256 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -3447,6 +3447,15 @@ } } job { + id: "android-chrome-pie-x86-wpt-android-specific" + realm: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "ci" + builder: "android-chrome-pie-x86-wpt-android-specific" + } +} +job { id: "android-chrome-pie-x86-wpt-fyi-rel" realm: "ci" buildbucket { @@ -6487,6 +6496,7 @@ triggers: "android-bfcache-rel" triggers: "android-binary-size-generator" triggers: "android-build-perf-developer" + triggers: "android-chrome-pie-x86-wpt-android-specific" triggers: "android-chrome-pie-x86-wpt-fyi-rel" triggers: "android-cronet-arm-dbg" triggers: "android-cronet-arm-rel"
diff --git a/infra/config/generated/testing/mixins.pyl b/infra/config/generated/testing/mixins.pyl index 61b5e79..99ad693 100644 --- a/infra/config/generated/testing/mixins.pyl +++ b/infra/config/generated/testing/mixins.pyl
@@ -1234,12 +1234,12 @@ 'xcode_15_main': { 'args': [ '--xcode-build-version', - '15a5209g', + '15a5219j', ], 'swarming': { 'named_caches': [ { - 'name': 'xcode_ios_15a5209g', + 'name': 'xcode_ios_15a5219j', 'path': 'Xcode.app', }, ],
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index 7ceb1d1..980fdbb 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -16,16 +16,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 118.0.5963.0', + 'description': 'Run with ash-chrome version 118.0.5964.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v118.0.5963.0', - 'revision': 'version:118.0.5963.0', + 'location': 'lacros_version_skew_tests_v118.0.5964.0', + 'revision': 'version:118.0.5964.0', }, ], },
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 39fb29b6a..3a7a4124 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -174,7 +174,7 @@ # A newer Xcode 14 RC used on beta bots. x14betabots = xcode_enum("14e222b"), # Default Xcode 15 for chromium iOS - x15main = xcode_enum("15a5209g"), + x15main = xcode_enum("15a5219j"), # A newer Xcode 15 version used on beta bots. x15betabots = xcode_enum("15a5219j"), # in use by ios-webkit-tot
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.fyi.star b/infra/config/subprojects/chromium/ci/chromium.android.fyi.star index 397eb01..9cfc8e3 100644 --- a/infra/config/subprojects/chromium/ci/chromium.android.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.android.fyi.star
@@ -53,6 +53,30 @@ ) ci.builder( + name = "android-chrome-pie-x86-wpt-android-specific", + builder_spec = builder_config.builder_spec( + gclient_config = builder_config.gclient_config( + config = "chromium", + apply_configs = ["android"], + ), + chromium_config = builder_config.chromium_config( + config = "android", + apply_configs = ["mb"], + build_config = builder_config.build_config.RELEASE, + target_bits = 32, + target_platform = builder_config.target_platform.ANDROID, + ), + android_config = builder_config.android_config(config = "x86_builder"), + build_gs_bucket = "chromium-android-archive", + ), + console_view_entry = consoles.console_view_entry( + category = "wpt|chrome", + short_name = "p-x86", + ), + experimental = True, +) + +ci.builder( name = "android-webview-pie-x86-wpt-fyi-rel", builder_spec = builder_config.builder_spec( gclient_config = builder_config.gclient_config(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index c04e507..a5e6c24 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -564,6 +564,11 @@ ) try_.builder( + name = "android-chrome-pie-x86-wpt-android-specific", + mirrors = ["ci/android-chrome-pie-x86-wpt-android-specific"], +) + +try_.builder( name = "android-webview-12-x64-dbg", mirrors = [ "ci/Android x64 Builder (dbg)",
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index 7ce5437a..f52c718 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "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_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ] }
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star index 8e070c7..91ab00f6 100644 --- a/infra/config/targets/mixins.star +++ b/infra/config/targets/mixins.star
@@ -1567,12 +1567,12 @@ name = "xcode_15_main", args = [ "--xcode-build-version", - "15a5209g", + "15a5219j", ], swarming = targets.swarming( named_caches = [ swarming.cache( - name = "xcode_ios_15a5209g", + name = "xcode_ios_15a5219j", path = "Xcode.app", ), ],
diff --git a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_java_script_feature.mm b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_java_script_feature.mm index d2f84df..3a366671 100644 --- a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_java_script_feature.mm +++ b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_java_script_feature.mm
@@ -37,7 +37,9 @@ AutofillBottomSheetJavaScriptFeature::AutofillBottomSheetJavaScriptFeature() : web::JavaScriptFeature( - web::ContentWorld::kIsolatedWorld, + // TODO(crbug.com/1175793): Move autofill code to kIsolatedWorld + // once all scripts are converted to JavaScriptFeatures. + web::ContentWorld::kPageContentWorld, {FeatureScript::CreateWithFilename( kScriptName, FeatureScript::InjectionTime::kDocumentStart,
diff --git a/ios/chrome/browser/safety_check/BUILD.gn b/ios/chrome/browser/safety_check/BUILD.gn index 7f347ab..d9ecc6a 100644 --- a/ios/chrome/browser/safety_check/BUILD.gn +++ b/ios/chrome/browser/safety_check/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "ios_chrome_safety_check_manager.h", "ios_chrome_safety_check_manager.mm", + "ios_chrome_safety_check_manager_observer_bridge.h", + "ios_chrome_safety_check_manager_observer_bridge.mm", ] public_deps = [ ":constants", @@ -25,6 +27,7 @@ "//ios/chrome/browser/upgrade:public", "//ios/chrome/common", ] + frameworks = [ "Foundation.framework" ] } source_set("factory") {
diff --git a/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.h b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.h new file mode 100644 index 0000000..af306e4e --- /dev/null +++ b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.h
@@ -0,0 +1,66 @@ +// 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 IOS_CHROME_BROWSER_SAFETY_CHECK_IOS_CHROME_SAFETY_CHECK_MANAGER_OBSERVER_BRIDGE_H_ +#define IOS_CHROME_BROWSER_SAFETY_CHECK_IOS_CHROME_SAFETY_CHECK_MANAGER_OBSERVER_BRIDGE_H_ + +#import "base/memory/raw_ptr.h" +#import "base/scoped_observation.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_constants.h" + +#import <Foundation/Foundation.h> + +// Objective-C protocol mirroring `IOSChromeSafetyCheckManagerObserver`. +@protocol SafetyCheckManagerObserver <NSObject> + +// Called whenever the Safety Check determines a change in the Password check +// state (i.e. when user has reused passwords, weak passwords, no compromised +// password, etc.) +- (void)passwordCheckStateChanged:(PasswordSafetyCheckState)state; + +// Called whenever the Safety Check determines a change in the Safe Browsing +// check state (i.e. when Safe Browsing is enabled, disabled, the check +// is currently running, etc.) +- (void)safeBrowsingCheckStateChanged:(SafeBrowsingSafetyCheckState)state; + +// Called whenever the Safety Check determines a change in the Update Chrome +// check state (i.e. when Chrome is up to date, Chrome is out of date, the +// check is currently running, etc.) +- (void)updateChromeCheckStateChanged:(UpdateChromeSafetyCheckState)state; + +// Called whenever the Safety Check begins the async process of evaluating the +// Password check, Safe Browsing check, and/or Update check. +- (void)runningStateChanged:(RunningSafetyCheckState)state; + +@end + +// Simple observer bridge that forwards all events to its delegate observer. +class SafetyCheckObserverBridge : public IOSChromeSafetyCheckManagerObserver { + public: + SafetyCheckObserverBridge(id<SafetyCheckManagerObserver> delegate, + IOSChromeSafetyCheckManager* manager); + + ~SafetyCheckObserverBridge() override; + + void PasswordCheckStateChanged(PasswordSafetyCheckState state) override; + void SafeBrowsingCheckStateChanged( + SafeBrowsingSafetyCheckState state) override; + void UpdateChromeCheckStateChanged( + UpdateChromeSafetyCheckState state) override; + void RunningStateChanged(RunningSafetyCheckState state) override; + void ManagerWillShutdown( + IOSChromeSafetyCheckManager* safety_check_manager) override; + + private: + __weak id<SafetyCheckManagerObserver> delegate_ = nil; + + base::ScopedObservation<IOSChromeSafetyCheckManager, + IOSChromeSafetyCheckManagerObserver> + safety_check_manager_observation_{this}; + + raw_ptr<IOSChromeSafetyCheckManager> safety_check_manager_; +}; + +#endif // IOS_CHROME_BROWSER_SAFETY_CHECK_IOS_CHROME_SAFETY_CHECK_MANAGER_OBSERVER_BRIDGE_H_
diff --git a/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.mm b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.mm new file mode 100644 index 0000000..8c9f78e --- /dev/null +++ b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.mm
@@ -0,0 +1,48 @@ +// 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 "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.h" + +#import "base/check.h" + +SafetyCheckObserverBridge::SafetyCheckObserverBridge( + id<SafetyCheckManagerObserver> delegate, + IOSChromeSafetyCheckManager* manager) + : delegate_(delegate), safety_check_manager_(manager) { + CHECK(delegate_); + CHECK(safety_check_manager_); + + safety_check_manager_observation_.Observe(manager); +} + +SafetyCheckObserverBridge::~SafetyCheckObserverBridge() { + if (safety_check_manager_) { + safety_check_manager_->RemoveObserver(this); + } +} + +void SafetyCheckObserverBridge::PasswordCheckStateChanged( + PasswordSafetyCheckState state) { + [delegate_ passwordCheckStateChanged:state]; +} + +void SafetyCheckObserverBridge::SafeBrowsingCheckStateChanged( + SafeBrowsingSafetyCheckState state) { + [delegate_ safeBrowsingCheckStateChanged:state]; +} + +void SafetyCheckObserverBridge::UpdateChromeCheckStateChanged( + UpdateChromeSafetyCheckState state) { + [delegate_ updateChromeCheckStateChanged:state]; +} + +void SafetyCheckObserverBridge::RunningStateChanged( + RunningSafetyCheckState state) { + [delegate_ runningStateChanged:state]; +} + +void SafetyCheckObserverBridge::ManagerWillShutdown( + IOSChromeSafetyCheckManager* safety_check_manager) { + safety_check_manager->RemoveObserver(this); +}
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 417491d0..6cc9adc 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -85,6 +85,7 @@ "//ios/chrome/browser/promos_manager:factory", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/safety_check", + "//ios/chrome/browser/safety_check:constants", "//ios/chrome/browser/safety_check:factory", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/segmentation_platform",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm index 54a8a23..9d20316a 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
@@ -44,10 +44,6 @@ const CGFloat kSeparatorHeight = 0.5; -// The margin spacing between the top horizontal StackView (containing the title -// and "See More" button) and the module's overall vertical container StackView. -const CGFloat kTitleStackViewTrailingMargin = 16.0f; - } // namespace @interface MagicStackModuleContainer () <UIContextMenuInteractionDelegate> @@ -104,6 +100,13 @@ _title.accessibilityIdentifier = [MagicStackModuleContainer titleStringForModule:type]; [titleStackView addArrangedSubview:_title]; + // `setContentHuggingPriority:` does not guarantee that titleStackView + // completely resists vertical expansion since UIStackViews do not have + // intrinsic contentSize. Constraining the title label to the StackView will + // ensure contentView expands. + [NSLayoutConstraint activateConstraints:@[ + [_title.bottomAnchor constraintEqualToAnchor:titleStackView.bottomAnchor] + ]]; if ([self shouldShowSeeMore]) { UIButton* showMoreButton = [[UIButton alloc] init]; @@ -117,6 +120,8 @@ showMoreButton.titleLabel.numberOfLines = 2; showMoreButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; showMoreButton.titleLabel.adjustsFontForContentSizeCategory = YES; + showMoreButton.contentHorizontalAlignment = + UIControlContentHorizontalAlignmentTrailing; [showMoreButton setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis: @@ -124,6 +129,9 @@ [showMoreButton addTarget:self action:@selector(seeMoreButtonWasTapped:) forControlEvents:UIControlEventTouchUpInside]; + [showMoreButton + setContentHuggingPriority:UILayoutPriorityDefaultHigh + forAxis:UILayoutConstraintAxisHorizontal]; [titleStackView addArrangedSubview:showMoreButton]; } @@ -140,8 +148,7 @@ // content view when dynamic type is set very large. [NSLayoutConstraint activateConstraints:@[ [titleStackView.widthAnchor - constraintEqualToAnchor:contentView.widthAnchor - constant:-kTitleStackViewTrailingMargin], + constraintEqualToConstant:[self contentViewWidth]], ]]; } if ([self shouldShowSeparator]) { @@ -166,17 +173,25 @@ _contentViewWidthAnchor = [contentView.widthAnchor constraintEqualToConstant:[self contentViewWidth]]; [NSLayoutConstraint activateConstraints:@[ _contentViewWidthAnchor ]]; - // Ensures that the modules do not become larger than kModuleMaxHeight. The - // less than or equal to constraint coupled with a UIViewNoIntrinsicMetric - // vertical intrinsic content size declaration allows for it to still - // vertically shrink to intrinsic content size. In practice, the largest - // module will determine the height of all the modules, but it should not - // grow taller than kModuleMaxHeight. The less than or equal to - // configuration is for the MVT when it lives outside of the Magic Stack to - // stay as close to its intrinsic size as possible. - [NSLayoutConstraint activateConstraints:@[ - [self.heightAnchor constraintLessThanOrEqualToConstant:kModuleMaxHeight] - ]]; + // Configures `contentView` to be the view willing to expand if needed to + // fill extra vertical space in the container. + [contentView + setContentCompressionResistancePriority:UILayoutPriorityDefaultLow + forAxis:UILayoutConstraintAxisVertical]; + // Ensures that the modules conforms to a height of kModuleMaxHeight. For + // the MVT when it lives outside of the Magic Stack to stay as close to its + // intrinsic size as possible, the constraint is configured to be less than + // or equal to. + if (_type == ContentSuggestionsModuleType::kMostVisited && + !ShouldPutMostVisitedSitesInMagicStack()) { + [NSLayoutConstraint activateConstraints:@[ + [self.heightAnchor constraintLessThanOrEqualToConstant:kModuleMaxHeight] + ]]; + } else { + [NSLayoutConstraint activateConstraints:@[ + [self.heightAnchor constraintEqualToConstant:kModuleMaxHeight] + ]]; + } [self addSubview:stackView]; AddSameConstraintsWithInsets(stackView, self, [self contentMargins]); @@ -231,6 +246,7 @@ break; case ContentSuggestionsModuleType::kMostVisited: case ContentSuggestionsModuleType::kShortcuts: + case ContentSuggestionsModuleType::kSafetyCheckMultiRow: contentMargins.bottom = kReducedContentBottomInset; break; default: @@ -338,7 +354,7 @@ case ContentSuggestionsModuleType::kSetUpListDefaultBrowser: case ContentSuggestionsModuleType::kSetUpListAutofill: case ContentSuggestionsModuleType::kSetUpListAllSet: - case ContentSuggestionsModuleType::kSafetyCheckMultiRow: + case ContentSuggestionsModuleType::kSafetyCheck: return YES; default: return NO;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h index 43b2e824..69ed354 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h
@@ -12,6 +12,7 @@ @class ContentSuggestionsMostVisitedItem; @class ContentSuggestionsReturnToRecentTabItem; @class ContentSuggestionsWhatsNewItem; +@class SafetyCheckState; enum class SetUpListItemType; @class SetUpListItemViewData; @class QuerySuggestionConfig; @@ -77,6 +78,9 @@ // complete. Calls `animations` to allow other things to be simultaneously // animated. - (void)showSetUpListDoneWithAnimations:(ProceduralBlock)animations; + +// Shows the Safety Check (Magic Stack) module with `state`. +- (void)showSafetyCheck:(SafetyCheckState*)state; @end #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm index a83f728..f60d74f 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -4,6 +4,8 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h" +#import <vector> + #import <AuthenticationServices/AuthenticationServices.h> #import <MaterialComponents/MaterialSnackbar.h> @@ -21,6 +23,7 @@ #import "components/ntp_tiles/metrics.h" #import "components/ntp_tiles/most_visited_sites.h" #import "components/ntp_tiles/ntp_tile.h" +#import "components/password_manager/core/browser/ui/credential_ui_entry.h" #import "components/pref_registry/pref_registry_syncable.h" #import "components/prefs/ios/pref_observer_bridge.h" #import "components/reading_list/core/reading_list_model.h" @@ -43,7 +46,12 @@ #import "ios/chrome/browser/ntp/set_up_list_item_type.h" #import "ios/chrome/browser/ntp/set_up_list_prefs.h" #import "ios/chrome/browser/ntp_tiles/most_visited_sites_observer_bridge.h" +#import "ios/chrome/browser/passwords/password_checkup_utils.h" #import "ios/chrome/browser/policy/policy_util.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_constants.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_factory.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_observer_bridge.h" #import "ios/chrome/browser/shared/coordinator/scene/scene_state.h" #import "ios/chrome/browser/shared/coordinator/scene/scene_state_browser_agent.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" @@ -76,6 +84,8 @@ #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_tile_saver.h" #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestions_section_information.h" +#import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h" +#import "ios/chrome/browser/ui/content_suggestions/safety_check/utils.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view_data.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/utils.h" #import "ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.h" @@ -118,6 +128,7 @@ MostVisitedSitesObserving, ReadingListModelBridgeObserver, PrefObserverDelegate, + SafetyCheckManagerObserver, SceneStateObserver, SetUpListDelegate> { std::unique_ptr<ntp_tiles::MostVisitedSites> _mostVisitedSites; @@ -199,6 +210,9 @@ syncer::SyncService* _syncService; // Used by SetUpList to get signed-in status. AuthenticationService* _authenticationService; + // Used by the Safety Check (Magic Stack) module for the current Safety Check + // state. + SafetyCheckState* _safetyCheckState; // Used by SetUpList to observe changes to signed-in status. std::unique_ptr<signin::IdentityManagerObserverBridge> _identityObserverBridge; @@ -207,6 +221,8 @@ // Observer for auth service status changes. std::unique_ptr<AuthenticationServiceObserverBridge> _authServiceObserverBridge; + // Observer for Safety Check changes. + std::unique_ptr<SafetyCheckObserverBridge> _safetyCheckManagerObserver; } #pragma mark - Public @@ -282,7 +298,54 @@ SceneStateBrowserAgent::FromBrowser(browser)->GetSceneState(); [sceneState addObserver:self]; _browser = browser; + + if (IsSafetyCheckMagicStackEnabled()) { + IOSChromeSafetyCheckManager* safetyCheckManager = + IOSChromeSafetyCheckManagerFactory::GetForBrowserState( + browser->GetBrowserState()); + + UpdateChromeSafetyCheckState initialUpdateChromeState = + safetyCheckManager->GetUpdateChromeCheckState(); + PasswordSafetyCheckState initialPasswordState = + safetyCheckManager->GetPasswordCheckState(); + SafeBrowsingSafetyCheckState initialSafeBrowsingState = + safetyCheckManager->GetSafeBrowsingCheckState(); + + base::Time lastRunTime = safetyCheckManager->GetLastSafetyCheckRunTime(); + + bool shouldRunSafetyCheck = CanRunSafetyCheck(lastRunTime); + + RunningSafetyCheckState initialRunningState = + shouldRunSafetyCheck ? RunningSafetyCheckState::kRunning + : RunningSafetyCheckState::kDefault; + + _safetyCheckState = [[SafetyCheckState alloc] + initWithUpdateChromeState:initialUpdateChromeState + passwordState:initialPasswordState + safeBrowsingState:initialSafeBrowsingState + runningState:initialRunningState]; + + std::vector<password_manager::CredentialUIEntry> insecureCredentials = + safetyCheckManager->GetInsecureCredentials(); + + password_manager::InsecurePasswordCounts counts = + password_manager::CountInsecurePasswordsPerInsecureType( + insecureCredentials); + + _safetyCheckState.weakPasswordsCount = counts.weak_count; + _safetyCheckState.reusedPasswordsCount = counts.reused_count; + _safetyCheckState.compromisedPasswordsCount = counts.compromised_count; + + _safetyCheckManagerObserver = std::make_unique<SafetyCheckObserverBridge>( + self, IOSChromeSafetyCheckManagerFactory::GetForBrowserState( + browser->GetBrowserState())); + + if (shouldRunSafetyCheck) { + safetyCheckManager->StartSafetyCheck(); + } + } } + return self; } @@ -667,6 +730,11 @@ (IsMagicStackEnabled() || ![self shouldShowSetUpList])) { [self.consumer setShortcutTilesWithConfigs:self.actionButtonItems]; } + + if (IsSafetyCheckMagicStackEnabled() && + _safetyCheckState.runningState == RunningSafetyCheckState::kDefault) { + [self.consumer showSafetyCheck:_safetyCheckState]; + } } // Updates `prefs::kIosSyncSegmentsNewTabPageDisplayCount` with the number of @@ -907,8 +975,17 @@ // different places in the Magic Stack depending on the Safety Check state(s). // However, for now, the module will simply be inserted at the front of the // Magic Stack. - [order insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheck)) - atIndex:0]; + + int check_issues_count = CheckIssuesCount(_safetyCheckState); + + if (check_issues_count > 1) { + [order + insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheckMultiRow)) + atIndex:0]; + } else { + [order insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheck)) + atIndex:0]; + } } // Returns YES if the conditions are right to display the Set Up List. @@ -1056,6 +1133,44 @@ } } +#pragma mark - SafetyCheckManagerObserver + +- (void)passwordCheckStateChanged:(PasswordSafetyCheckState)state { + _safetyCheckState.passwordState = state; + + IOSChromeSafetyCheckManager* safetyCheckManager = + IOSChromeSafetyCheckManagerFactory::GetForBrowserState( + self.browser->GetBrowserState()); + + std::vector<password_manager::CredentialUIEntry> insecureCredentials = + safetyCheckManager->GetInsecureCredentials(); + + password_manager::InsecurePasswordCounts counts = + password_manager::CountInsecurePasswordsPerInsecureType( + insecureCredentials); + + _safetyCheckState.weakPasswordsCount = counts.weak_count; + _safetyCheckState.reusedPasswordsCount = counts.reused_count; + _safetyCheckState.compromisedPasswordsCount = counts.compromised_count; +} + +- (void)safeBrowsingCheckStateChanged:(SafeBrowsingSafetyCheckState)state { + _safetyCheckState.safeBrowsingState = state; +} + +- (void)updateChromeCheckStateChanged:(UpdateChromeSafetyCheckState)state { + _safetyCheckState.updateChromeState = state; +} + +- (void)runningStateChanged:(RunningSafetyCheckState)state { + _safetyCheckState.runningState = state; + + // Ensures the consumer gets the latest Safety Check state only when the + // running state changes; this avoids calling the consumer every time an + // individual check state changes. + [self.consumer showSafetyCheck:_safetyCheckState]; +} + #pragma mark - ReadingListModelBridgeObserver - (void)readingListModelLoaded:(const ReadingListModel*)model {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index 6640ed4..ea9637a5 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -38,6 +38,7 @@ #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view.h" +#import "ios/chrome/browser/ui/content_suggestions/safety_check/utils.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view_data.h" #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_view.h" @@ -125,8 +126,13 @@ NSMutableArray<ContentSuggestionsShortcutTileView*>* shortcutsViews; // The SetUpListView, if it is currently being displayed. @property(nonatomic, strong) SetUpListView* setUpListView; +// The current state of the Safety Check. +@property(nonatomic, strong) SafetyCheckState* safetyCheckState; // The SafetyCheckView, if it is currently being displayed. @property(nonatomic, strong) SafetyCheckView* safetyCheckView; +// Module Container for the `safetyCheckView` when being shown in Magic Stack. +@property(nonatomic, strong) + MagicStackModuleContainer* safetyCheckModuleContainer; @end @implementation ContentSuggestionsViewController { @@ -230,6 +236,10 @@ } } + if (IsSafetyCheckMagicStackEnabled() && self.safetyCheckState) { + [self createSafetyCheck:self.safetyCheckState]; + } + // Only Create Magic Stack if the ranking has been received. It can be delayed // to after -viewDidLoad if fecthing from Segmentation Platform. if (IsMagicStackEnabled() && _magicStackRankReceived) { @@ -646,6 +656,29 @@ }]; } +- (void)showSafetyCheck:(SafetyCheckState*)state { + _safetyCheckState = state; + + if (!self.viewLoaded) { + return; + } + + if (self.safetyCheckModuleContainer) { + [self.safetyCheckModuleContainer removeFromSuperview]; + } + + [self createSafetyCheck:state]; + + int checkIssuesCount = CheckIssuesCount(state); + + ContentSuggestionsModuleType type = + checkIssuesCount > 1 ? ContentSuggestionsModuleType::kSafetyCheckMultiRow + : ContentSuggestionsModuleType::kSafetyCheck; + + [_magicStack insertArrangedSubview:self.safetyCheckModuleContainer + atIndex:[self indexForMagicStackModule:type]]; +} + - (CGFloat)contentSuggestionsHeight { CGFloat height = 0; if ([self.mostVisitedViews count] > 0 && @@ -884,6 +917,25 @@ } } +- (void)createSafetyCheck:(SafetyCheckState*)state { + self.safetyCheckState = state; + + self.safetyCheckView = [[SafetyCheckView alloc] initWithState:state]; + + self.safetyCheckView.delegate = self.audience; + + int checkIssuesCount = CheckIssuesCount(state); + + ContentSuggestionsModuleType type = + checkIssuesCount > 1 ? ContentSuggestionsModuleType::kSafetyCheckMultiRow + : ContentSuggestionsModuleType::kSafetyCheck; + + self.safetyCheckModuleContainer = [[MagicStackModuleContainer alloc] + initWithContentView:self.safetyCheckView + type:type + delegate:self]; +} + // Add the elements in `mostVisitedViews` into `verticalStackView`. - (void)populateMostVisitedModule { for (ContentSuggestionsMostVisitedTileView* view in self.mostVisitedViews) { @@ -1025,28 +1077,9 @@ } case ContentSuggestionsModuleType::kSafetyCheck: case ContentSuggestionsModuleType::kSafetyCheckMultiRow: { - // TODO(crbug.com/1472382): In a follow-up CL, this information will - // come from the new Safety Check Manager. For now, this is placeholder - // showing the default state. - SafetyCheckState* defaultState = [[SafetyCheckState alloc] - initWithUpdateChromeState:UpdateChromeSafetyCheckState::kDefault - passwordState:PasswordSafetyCheckState::kDefault - safeBrowsingState:SafeBrowsingSafetyCheckState::kDefault - runningState:RunningSafetyCheckState::kDefault]; - - self.safetyCheckView = - [[SafetyCheckView alloc] initWithState:defaultState]; - - self.safetyCheckView.delegate = self.audience; - - MagicStackModuleContainer* safetyCheckModule = - [[MagicStackModuleContainer alloc] - initWithContentView:self.safetyCheckView - type:type - delegate:self]; - - [_magicStack addArrangedSubview:safetyCheckModule]; - + if (IsSafetyCheckMagicStackEnabled()) { + [_magicStack addArrangedSubview:self.safetyCheckModuleContainer]; + } break; } default:
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h index 4f47073..5722a58 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h
@@ -24,16 +24,25 @@ runningState:(RunningSafetyCheckState)runningState; // The current state of the Update Chrome check. -@property(nonatomic, readonly) UpdateChromeSafetyCheckState updateChromeState; +@property(nonatomic, readwrite) UpdateChromeSafetyCheckState updateChromeState; // The current state of the Password check. -@property(nonatomic, readonly) PasswordSafetyCheckState passwordState; +@property(nonatomic, readwrite) PasswordSafetyCheckState passwordState; // The current state of the Safe Browsing check. -@property(nonatomic, readonly) SafeBrowsingSafetyCheckState safeBrowsingState; +@property(nonatomic, readwrite) SafeBrowsingSafetyCheckState safeBrowsingState; // The Safety Check running state. -@property(nonatomic, readonly) RunningSafetyCheckState runningState; +@property(nonatomic, readwrite) RunningSafetyCheckState runningState; + +// The number of weak passwords found by the Password check. +@property(nonatomic, assign) NSInteger weakPasswordsCount; + +// The number of reused passwords found by the Password check. +@property(nonatomic, assign) NSInteger reusedPasswordsCount; + +// The number of compromised passwords found by the Password check. +@property(nonatomic, assign) NSInteger compromisedPasswordsCount; @end
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view.mm b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view.mm index 71afabb..e48023d 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view.mm +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view.mm
@@ -10,31 +10,9 @@ #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_item_view.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h" #import "ios/chrome/browser/ui/content_suggestions/safety_check/types.h" +#import "ios/chrome/browser/ui/content_suggestions/safety_check/utils.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" -namespace { - -// Returns the number of check issue types found given `state`. -int CheckIssuesCount(SafetyCheckState* state) { - int count = 0; - - if (state.updateChromeState != UpdateChromeSafetyCheckState::kUpToDate) { - count++; - } - - if (state.safeBrowsingState != SafeBrowsingSafetyCheckState::kSafe) { - count++; - } - - if (state.passwordState != PasswordSafetyCheckState::kSafe) { - count++; - } - - return count; -} - -} // namespace - @interface SafetyCheckView () <SafetyCheckItemViewTapDelegate> @end @@ -150,8 +128,11 @@ // Password check if (_state.passwordState != PasswordSafetyCheckState::kSafe) { SafetyCheckItemView* passwordView = [[SafetyCheckItemView alloc] - initWithItemType:SafetyCheckItemType::kPassword - layoutType:SafetyCheckItemLayoutType::kCompact]; + initWithItemType:SafetyCheckItemType::kPassword + layoutType:SafetyCheckItemLayoutType::kCompact + weakPasswordsCount:_state.weakPasswordsCount + reusedPasswordsCount:_state.reusedPasswordsCount + compromisedPasswordsCount:_state.compromisedPasswordsCount]; passwordView.tapDelegate = self; @@ -176,6 +157,8 @@ MultiRowContainerView* multiRowContainer = [[MultiRowContainerView alloc] initWithViews:safetyCheckItems]; + multiRowContainer.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:multiRowContainer]; AddSameConstraints(multiRowContainer, self); @@ -194,8 +177,11 @@ if (_state.passwordState != PasswordSafetyCheckState::kSafe) { view = [[SafetyCheckItemView alloc] - initWithItemType:SafetyCheckItemType::kPassword - layoutType:SafetyCheckItemLayoutType::kHero]; + initWithItemType:SafetyCheckItemType::kPassword + layoutType:SafetyCheckItemLayoutType::kHero + weakPasswordsCount:_state.weakPasswordsCount + reusedPasswordsCount:_state.reusedPasswordsCount + compromisedPasswordsCount:_state.compromisedPasswordsCount]; } if (_state.safeBrowsingState != SafeBrowsingSafetyCheckState::kSafe) {
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/utils.h b/ios/chrome/browser/ui/content_suggestions/safety_check/utils.h index cd2ecaf3..84da5249 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/utils.h +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/utils.h
@@ -9,6 +9,8 @@ #import <UIKit/UIKit.h> +#import "base/time/time.h" + @protocol ApplicationCommands; namespace password_manager { struct CredentialUIEntry; @@ -27,4 +29,10 @@ std::vector<password_manager::CredentialUIEntry>& credentials, id<ApplicationCommands> handler); +// Returns the number of check issues found given `state`. +int CheckIssuesCount(SafetyCheckState* state); + +// Returns true if the Safety Check can be run given `last_run_time`. +bool CanRunSafetyCheck(base::Time last_run_time); + #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_SAFETY_CHECK_UTILS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm b/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm index 0276044..8021a11 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/utils.mm
@@ -9,13 +9,18 @@ #import "components/password_manager/core/common/password_manager_features.h" #import "components/version_info/version_info.h" #import "ios/chrome/browser/passwords/password_checkup_utils.h" +#import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_constants.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" #import "ios/chrome/browser/shared/public/commands/open_new_tab_command.h" +#import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h" #import "ios/chrome/common/channel_info.h" #import "url/gurl.h" namespace { +// The Safety Check should only be run once every 24 hours. +constexpr base::TimeDelta kSafetyCheckRunThreshold = base::Hours(24); + // Returns the number of unique warning types found in `counts`. // // NOTE: Only considers compromised, reused, and weak passwords. (Does not @@ -113,3 +118,41 @@ [handler showPasswordCheckupPageForReferrer: password_manager::PasswordCheckReferrer::kSafetyCheckMagicStack]; } + +int CheckIssuesCount(SafetyCheckState* state) { + bool invalid_update_chrome_state = + state.updateChromeState == UpdateChromeSafetyCheckState::kOutOfDate; + + bool invalid_password_state = + state.passwordState == + PasswordSafetyCheckState::kUnmutedCompromisedPasswords || + state.passwordState == PasswordSafetyCheckState::kReusedPasswords || + state.passwordState == PasswordSafetyCheckState::kWeakPasswords; + + bool invalid_safe_browsing_state = + state.safeBrowsingState == SafeBrowsingSafetyCheckState::kUnsafe; + + int invalid_check_count = 0; + + std::vector<bool> invalid_checks = {invalid_update_chrome_state, + invalid_password_state, + invalid_safe_browsing_state}; + + for (bool invalid_check : invalid_checks) { + if (invalid_check) { + invalid_check_count++; + } + } + + return invalid_check_count; +} + +bool CanRunSafetyCheck(base::Time last_run_time) { + base::TimeDelta last_run_age = base::Time::Now() - last_run_time; + + if (last_run_age > kSafetyCheckRunThreshold) { + return true; + } + + return false; +}
diff --git a/media/base/ipc/media_param_traits_macros.h b/media/base/ipc/media_param_traits_macros.h index 3067262..9fa3d4b7 100644 --- a/media/base/ipc/media_param_traits_macros.h +++ b/media/base/ipc/media_param_traits_macros.h
@@ -106,7 +106,7 @@ media::MediaLogRecord::Type::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(media::MediaStatus::State, - media::MediaStatus::State::STATE_MAX) + media::MediaStatus::State::kStateMax) IPC_ENUM_TRAITS_MAX_VALUE(media::OutputDeviceStatus, media::OUTPUT_DEVICE_STATUS_MAX)
diff --git a/media/base/media_status.h b/media/base/media_status.h index 4335116c..13c5006 100644 --- a/media/base/media_status.h +++ b/media/base/media_status.h
@@ -11,19 +11,15 @@ namespace media { -// Describes the current state of media being controlled via the MediaController -// interface. This is a copy of the media_router.mojom.MediaStatus interface, -// without the cast specific portions. -// TODO(https://crbug.com/820277): Deduplicate media_router::MediaStatus. struct MEDIA_EXPORT MediaStatus { public: enum class State { - UNKNOWN, - PLAYING, - PAUSED, - BUFFERING, - STOPPED, - STATE_MAX = STOPPED, + kUnknown, + kPlaying, + kPaused, + kBuffering, + kStopped, + kStateMax = kStopped, }; MediaStatus(); @@ -49,7 +45,7 @@ // If this is true, the media's current playback position can be changed. bool can_seek = false; - State state = State::UNKNOWN; + State state = State::kUnknown; bool is_muted = false;
diff --git a/media/gpu/h265_decoder.cc b/media/gpu/h265_decoder.cc index 0ecff51..c622ca0 100644 --- a/media/gpu/h265_decoder.cc +++ b/media/gpu/h265_decoder.cc
@@ -79,6 +79,18 @@ H265Decoder::H265Accelerator::~H265Accelerator() = default; +void H265Decoder::H265Accelerator::ProcessVPS( + const H265VPS* vps, + base::span<const uint8_t> vps_nalu_data) {} + +void H265Decoder::H265Accelerator::ProcessSPS( + const H265SPS* sps, + base::span<const uint8_t> sps_nalu_data) {} + +void H265Decoder::H265Accelerator::ProcessPPS( + const H265PPS* pps, + base::span<const uint8_t> pps_nalu_data) {} + H265Decoder::H265Accelerator::Status H265Decoder::H265Accelerator::SetStream( base::span<const uint8_t> stream, const DecryptConfig* decrypt_config) { @@ -216,6 +228,7 @@ } // 8.1.2 We only want nuh_layer_id of zero. + // TODO(crbug.com/1331597): Support alpha on macOS. if (curr_nalu_->nuh_layer_id) { DVLOG(4) << "Skipping NALU with nuh_layer_id=" << curr_nalu_->nuh_layer_id; @@ -317,13 +330,30 @@ last_slice_hdr_.swap(curr_slice_hdr_); curr_slice_hdr_.reset(); break; + case H265NALU::VPS_NUT: + CHECK_ACCELERATOR_RESULT(FinishPrevFrameIfPresent()); + int vps_id; + par_res = parser_.ParseVPS(&vps_id); + if (par_res != H265Parser::kOk) { + SET_ERROR_AND_RETURN(); + } + accelerator_->ProcessVPS( + parser_.GetVPS(vps_id), + base::span<const uint8_t>( + curr_nalu_->data, + base::checked_cast<size_t>(curr_nalu_->size))); + break; case H265NALU::SPS_NUT: CHECK_ACCELERATOR_RESULT(FinishPrevFrameIfPresent()); int sps_id; par_res = parser_.ParseSPS(&sps_id); if (par_res != H265Parser::kOk) SET_ERROR_AND_RETURN(); - + accelerator_->ProcessSPS( + parser_.GetSPS(sps_id), + base::span<const uint8_t>( + curr_nalu_->data, + base::checked_cast<size_t>(curr_nalu_->size))); break; case H265NALU::PPS_NUT: CHECK_ACCELERATOR_RESULT(FinishPrevFrameIfPresent()); @@ -331,6 +361,11 @@ par_res = parser_.ParsePPS(*curr_nalu_, &pps_id); if (par_res != H265Parser::kOk) SET_ERROR_AND_RETURN(); + accelerator_->ProcessPPS( + parser_.GetPPS(pps_id), + base::span<const uint8_t>( + curr_nalu_->data, + base::checked_cast<size_t>(curr_nalu_->size))); // For ARC CTS tests they expect us to request the buffers after only // processing the SPS/PPS, we can't wait until we get the first IDR. To
diff --git a/media/gpu/h265_decoder.h b/media/gpu/h265_decoder.h index 32a00d55..9cfeb79d 100644 --- a/media/gpu/h265_decoder.h +++ b/media/gpu/h265_decoder.h
@@ -80,6 +80,24 @@ // this situation as normal and return from Decode() with kRanOutOfSurfaces. virtual scoped_refptr<H265Picture> CreateH265Picture() = 0; + // Provides the raw NALU data for a VPS. The |vps| passed to + // SubmitFrameMetadata() is always the most recent VPS passed to + // ProcessVPS() with the same |vps_video_parameter_set_id|. + virtual void ProcessVPS(const H265VPS* vps, + base::span<const uint8_t> vps_nalu_data); + + // Provides the raw NALU data for an SPS. The |sps| passed to + // SubmitFrameMetadata() is always the most recent SPS passed to + // ProcessSPS() with the same |sps_video_parameter_set_id|. + virtual void ProcessSPS(const H265SPS* sps, + base::span<const uint8_t> sps_nalu_data); + + // Provides the raw NALU data for a PPS. The |pps| passed to + // SubmitFrameMetadata() is always the most recent PPS passed to + // ProcessPPS() with the same |pps_pic_parameter_set_id|. + virtual void ProcessPPS(const H265PPS* pps, + base::span<const uint8_t> pps_nalu_data); + // Submit metadata for the current frame, providing the current |sps|, |pps| // and |slice_hdr| for it. |ref_pic_list| contains the set of pictures as // described in 8.3.2 from the lists RefPicSetLtCurr, RefPicSetLtFoll,
diff --git a/media/gpu/ipc/service/media_gpu_channel.h b/media/gpu/ipc/service/media_gpu_channel.h index ffe2339..7069f79 100644 --- a/media/gpu/ipc/service/media_gpu_channel.h +++ b/media/gpu/ipc/service/media_gpu_channel.h
@@ -24,7 +24,7 @@ ~MediaGpuChannel(); private: - const raw_ptr<gpu::GpuChannel> channel_; + const raw_ptr<gpu::GpuChannel, DanglingUntriaged> channel_; AndroidOverlayMojoFactoryCB overlay_factory_cb_; };
diff --git a/media/gpu/mac/BUILD.gn b/media/gpu/mac/BUILD.gn index d90a594..9783f6c6 100644 --- a/media/gpu/mac/BUILD.gn +++ b/media/gpu/mac/BUILD.gn
@@ -42,6 +42,12 @@ "vt_video_encode_accelerator_mac.cc", "vt_video_encode_accelerator_mac.h", ] + if (enable_hevc_parser_and_hw_decoder) { + sources += [ + "video_toolbox_h265_accelerator.cc", + "video_toolbox_h265_accelerator.h", + ] + } public_deps = [ "//third_party/webrtc_overrides:webrtc_component" ] frameworks = [ "CoreFoundation.framework", @@ -91,4 +97,7 @@ "vp9_super_frame_bitstream_filter_unittest.cc", "vt_config_util_unittest.cc", ] + if (enable_hevc_parser_and_hw_decoder) { + sources += [ "video_toolbox_h265_accelerator_unittest.cc" ] + } }
diff --git a/media/gpu/mac/video_toolbox_decompression_interface.cc b/media/gpu/mac/video_toolbox_decompression_interface.cc index 19c1ae1..e14d022 100644 --- a/media/gpu/mac/video_toolbox_decompression_interface.cc +++ b/media/gpu/mac/video_toolbox_decompression_interface.cc
@@ -184,10 +184,17 @@ decoder_config, kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder, kCFBooleanTrue); + + // We don't have software HEVC decoders to fall back to. + // TODO(crbug.com/1331597): Plumb hardware requirement from the accelerator. + FourCharCode codec_type = CMFormatDescriptionGetMediaSubType(format); + bool require_hardware = (codec_type != kCMVideoCodecType_HEVC) && + (codec_type != kCMVideoCodecType_HEVCWithAlpha); + CFDictionarySetValue( decoder_config, kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder, - kCFBooleanTrue); + require_hardware ? kCFBooleanTrue : kCFBooleanFalse); #endif if (!decompression_session_->Create(format, decoder_config)) {
diff --git a/media/gpu/mac/video_toolbox_h264_accelerator.h b/media/gpu/mac/video_toolbox_h264_accelerator.h index 13fb40d..2c6ae32 100644 --- a/media/gpu/mac/video_toolbox_h264_accelerator.h +++ b/media/gpu/mac/video_toolbox_h264_accelerator.h
@@ -69,8 +69,8 @@ OutputCB output_cb_; // Raw parameter set bytes that have been observed. - base::flat_map<int, std::vector<uint8_t>> seen_sps_data_; - base::flat_map<int, std::vector<uint8_t>> seen_pps_data_; + base::flat_map<int, std::vector<uint8_t>> seen_sps_data_; // IDs can be 0-31 + base::flat_map<int, std::vector<uint8_t>> seen_pps_data_; // IDs can be 0-255 // Raw parameter set bytes used to produce |active_format_|, so that they // can be checked for changes.
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator.cc b/media/gpu/mac/video_toolbox_h265_accelerator.cc new file mode 100644 index 0000000..4f4a75e --- /dev/null +++ b/media/gpu/mac/video_toolbox_h265_accelerator.cc
@@ -0,0 +1,272 @@ +// 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 "media/gpu/mac/video_toolbox_h265_accelerator.h" + +#include <utility> + +#include "base/apple/osstatus_logging.h" +#include "base/sys_byteorder.h" +#include "media/base/media_log.h" + +namespace media { + +namespace { +constexpr size_t kNALUHeaderLength = 4; +} // namespace + +VideoToolboxH265Accelerator::VideoToolboxH265Accelerator( + std::unique_ptr<MediaLog> media_log, + DecodeCB decode_cb, + OutputCB output_cb) + : media_log_(std::move(media_log)), + decode_cb_(std::move(decode_cb)), + output_cb_(std::move(output_cb)) { + DVLOG(1) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +VideoToolboxH265Accelerator::~VideoToolboxH265Accelerator() { + DVLOG(1) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +scoped_refptr<H265Picture> VideoToolboxH265Accelerator::CreateH265Picture() { + DVLOG(4) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return base::MakeRefCounted<H265Picture>(); +} + +void VideoToolboxH265Accelerator::ProcessVPS( + const H265VPS* vps, + base::span<const uint8_t> vps_nalu_data) { + DVLOG(3) << __func__ << ": vps_video_parameter_set_id=" + << vps->vps_video_parameter_set_id; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + seen_vps_data_[vps->vps_video_parameter_set_id] = + std::vector<uint8_t>(vps_nalu_data.begin(), vps_nalu_data.end()); +} + +void VideoToolboxH265Accelerator::ProcessSPS( + const H265SPS* sps, + base::span<const uint8_t> sps_nalu_data) { + DVLOG(3) << __func__ + << ": sps_seq_parameter_set_id=" << sps->sps_seq_parameter_set_id; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + seen_sps_data_[sps->sps_seq_parameter_set_id] = + std::vector<uint8_t>(sps_nalu_data.begin(), sps_nalu_data.end()); +} + +void VideoToolboxH265Accelerator::ProcessPPS( + const H265PPS* pps, + base::span<const uint8_t> pps_nalu_data) { + DVLOG(3) << __func__ + << ": pps_pic_parameter_set_id=" << pps->pps_pic_parameter_set_id + << " pps_seq_parameter_set_id=" << pps->pps_seq_parameter_set_id; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + seen_pps_data_[pps->pps_pic_parameter_set_id] = + std::vector<uint8_t>(pps_nalu_data.begin(), pps_nalu_data.end()); +} + +VideoToolboxH265Accelerator::Status +VideoToolboxH265Accelerator::SubmitFrameMetadata( + const H265SPS* sps, + const H265PPS* pps, + const H265SliceHeader* slice_hdr, + const H265Picture::Vector& ref_pic_list, + const H265Picture::Vector& ref_pic_set_lt_curr, + const H265Picture::Vector& ref_pic_set_st_curr_after, + const H265Picture::Vector& ref_pic_set_st_curr_before, + scoped_refptr<H265Picture> pic) { + DVLOG(3) << __func__ << ":" + << " sps_video_parameter_set_id=" << sps->sps_video_parameter_set_id + << " sps_seq_parameter_set_id=" << sps->sps_seq_parameter_set_id + << " pps_pic_parameter_set_id=" << pps->pps_pic_parameter_set_id; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + slice_nalu_data_.clear(); + + // H265Decoder ignores VPS, so it doesn't check whether a valid one was + // provided. + if (!seen_vps_data_.contains(sps->sps_video_parameter_set_id)) { + MEDIA_LOG(ERROR, media_log_.get()) << "Missing VPS"; + return Status::kFail; + } + + // Detect format changes. + DCHECK(seen_sps_data_.contains(sps->sps_seq_parameter_set_id)); + DCHECK(seen_pps_data_.contains(pps->pps_pic_parameter_set_id)); + std::vector<uint8_t>& vps_data = + seen_vps_data_[sps->sps_video_parameter_set_id]; + std::vector<uint8_t>& sps_data = + seen_sps_data_[sps->sps_seq_parameter_set_id]; + std::vector<uint8_t>& pps_data = + seen_pps_data_[pps->pps_pic_parameter_set_id]; + if (vps_data != active_vps_data_ || sps_data != active_sps_data_ || + pps_data != active_pps_data_) { + active_format_.reset(); + + const uint8_t* nalu_data[3] = {vps_data.data(), sps_data.data(), + pps_data.data()}; + size_t nalu_size[3] = {vps_data.size(), sps_data.size(), pps_data.size()}; + OSStatus status = CMVideoFormatDescriptionCreateFromHEVCParameterSets( + kCFAllocatorDefault, + 3, // parameter_set_count + nalu_data, // parameter_set_pointers + nalu_size, // parameter_set_sizes + kNALUHeaderLength, // nal_unit_header_length + nullptr, // extensions + active_format_.InitializeInto()); + if (status != noErr) { + OSSTATUS_MEDIA_LOG(ERROR, status, media_log_.get()) + << "CMVideoFormatDescriptionCreateFromHEVCParameterSets()"; + return Status::kFail; + } + + active_vps_data_ = vps_data; + active_sps_data_ = sps_data; + active_pps_data_ = pps_data; + } + + return Status::kOk; +} + +VideoToolboxH265Accelerator::Status VideoToolboxH265Accelerator::SubmitSlice( + const H265SPS* sps, + const H265PPS* pps, + const H265SliceHeader* slice_hdr, + const H265Picture::Vector& ref_pic_list0, + const H265Picture::Vector& ref_pic_list1, + const H265Picture::Vector& ref_pic_set_lt_curr, + const H265Picture::Vector& ref_pic_set_st_curr_after, + const H265Picture::Vector& ref_pic_set_st_curr_before, + scoped_refptr<H265Picture> pic, + const uint8_t* data, + size_t size, + const std::vector<SubsampleEntry>& subsamples) { + DVLOG(3) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO(crbug.com/1331597): Implement kMinOutputsBeforeRASL workaround. + slice_nalu_data_.push_back(base::make_span(data, size)); + return Status::kOk; +} + +VideoToolboxH265Accelerator::Status VideoToolboxH265Accelerator::SubmitDecode( + scoped_refptr<H265Picture> pic) { + DVLOG(3) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // Determine the final size of the converted bitstream. + size_t data_size = 0; + for (const auto& nalu_data : slice_nalu_data_) { + data_size += kNALUHeaderLength + nalu_data.size(); + } + + // Allocate a buffer. + base::apple::ScopedCFTypeRef<CMBlockBufferRef> data; + OSStatus status = CMBlockBufferCreateWithMemoryBlock( + kCFAllocatorDefault, + nullptr, // memory_block + data_size, // block_length + kCFAllocatorDefault, // block_allocator + nullptr, // custom_block_source + 0, // offset_to_data + data_size, // data_length + 0, // flags + data.InitializeInto()); + if (status != noErr) { + OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferCreateWithMemoryBlock()"; + OSSTATUS_MEDIA_LOG(ERROR, status, media_log_.get()) + << "CMBlockBufferCreateWithMemoryBlock()"; + return Status::kFail; + } + + status = CMBlockBufferAssureBlockMemory(data); + if (status != noErr) { + OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferAssureBlockMemory()"; + OSSTATUS_MEDIA_LOG(ERROR, status, media_log_.get()) + << "CMBlockBufferAssureBlockMemory()"; + return Status::kFail; + } + + // Copy each NALU into the buffer, prefixed with a length header. + size_t offset = 0; + for (const auto& nalu_data : slice_nalu_data_) { + // Write length header. + uint32_t header = + base::HostToNet32(static_cast<uint32_t>(nalu_data.size())); + status = + CMBlockBufferReplaceDataBytes(&header, data, offset, kNALUHeaderLength); + if (status != noErr) { + OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferReplaceDataBytes()"; + OSSTATUS_MEDIA_LOG(ERROR, status, media_log_.get()) + << "CMBlockBufferReplaceDataBytes()"; + return Status::kFail; + } + offset += kNALUHeaderLength; + + // Write NALU data. + status = CMBlockBufferReplaceDataBytes(nalu_data.data(), data, offset, + nalu_data.size()); + if (status != noErr) { + OSSTATUS_DLOG(ERROR, status) << "CMBlockBufferReplaceDataBytes()"; + OSSTATUS_MEDIA_LOG(ERROR, status, media_log_.get()) + << "CMBlockBufferReplaceDataBytes()"; + return Status::kFail; + } + offset += nalu_data.size(); + } + + // Wrap in a sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample; + status = CMSampleBufferCreate(kCFAllocatorDefault, + data, // data_buffer + true, // data_ready + nullptr, // make_data_ready_callback + nullptr, // make_data_ready_refcon + active_format_, // format_description + 1, // num_samples + 0, // num_sample_timing_entries + nullptr, // sample_timing_array + 1, // num_sample_size_entries + &data_size, // sample_size_array + sample.InitializeInto()); + if (status != noErr) { + OSSTATUS_MEDIA_LOG(ERROR, status, media_log_.get()) + << "CMSampleBufferCreate()"; + return Status::kFail; + } + + decode_cb_.Run(std::move(sample), std::move(pic)); + return Status::kOk; +} + +bool VideoToolboxH265Accelerator::OutputPicture( + scoped_refptr<H265Picture> pic) { + DVLOG(3) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // We don't care about outputs, just pass them along. + output_cb_.Run(std::move(pic)); + return true; +} + +void VideoToolboxH265Accelerator::Reset() { + DVLOG(1) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + seen_vps_data_.clear(); + seen_sps_data_.clear(); + seen_pps_data_.clear(); + active_vps_data_.clear(); + active_sps_data_.clear(); + active_pps_data_.clear(); + active_format_.reset(); + slice_nalu_data_.clear(); +} + +bool VideoToolboxH265Accelerator::IsChromaSamplingSupported( + VideoChromaSampling format) { + return true; +} + +} // namespace media
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator.h b/media/gpu/mac/video_toolbox_h265_accelerator.h new file mode 100644 index 0000000..8ccc9682 --- /dev/null +++ b/media/gpu/mac/video_toolbox_h265_accelerator.h
@@ -0,0 +1,101 @@ +// 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 MEDIA_GPU_MAC_VIDEO_TOOLBOX_H265_ACCELERATOR_H_ +#define MEDIA_GPU_MAC_VIDEO_TOOLBOX_H265_ACCELERATOR_H_ + +#include <CoreMedia/CoreMedia.h> + +#include <stdint.h> +#include <memory> +#include <vector> + +#include "base/apple/scoped_cftyperef.h" +#include "base/containers/flat_map.h" +#include "base/containers/span.h" +#include "base/functional/callback.h" +#include "base/sequence_checker.h" +#include "media/gpu/h265_decoder.h" +#include "media/gpu/media_gpu_export.h" + +namespace media { + +class MediaLog; + +class MEDIA_GPU_EXPORT VideoToolboxH265Accelerator + : public H265Decoder::H265Accelerator { + public: + using DecodeCB = base::RepeatingCallback<void( + base::apple::ScopedCFTypeRef<CMSampleBufferRef>, + scoped_refptr<CodecPicture>)>; + using OutputCB = base::RepeatingCallback<void(scoped_refptr<CodecPicture>)>; + + VideoToolboxH265Accelerator(std::unique_ptr<MediaLog> media_log, + DecodeCB decode_cb, + OutputCB output_cb); + ~VideoToolboxH265Accelerator() override; + + // H265Accelerator implementation. + scoped_refptr<H265Picture> CreateH265Picture() override; + void ProcessVPS(const H265VPS* vps, + base::span<const uint8_t> vps_nalu_data) override; + void ProcessSPS(const H265SPS* sps, + base::span<const uint8_t> sps_nalu_data) override; + void ProcessPPS(const H265PPS* pps, + base::span<const uint8_t> pps_nalu_data) override; + Status SubmitFrameMetadata( + const H265SPS* sps, + const H265PPS* pps, + const H265SliceHeader* slice_hdr, + const H265Picture::Vector& ref_pic_list, + const H265Picture::Vector& ref_pic_set_lt_curr, + const H265Picture::Vector& ref_pic_set_st_curr_after, + const H265Picture::Vector& ref_pic_set_st_curr_before, + scoped_refptr<H265Picture> pic) override; + Status SubmitSlice(const H265SPS* sps, + const H265PPS* pps, + const H265SliceHeader* slice_hdr, + const H265Picture::Vector& ref_pic_list0, + const H265Picture::Vector& ref_pic_list1, + const H265Picture::Vector& ref_pic_set_lt_curr, + const H265Picture::Vector& ref_pic_set_st_curr_after, + const H265Picture::Vector& ref_pic_set_st_curr_before, + scoped_refptr<H265Picture> pic, + const uint8_t* data, + size_t size, + const std::vector<SubsampleEntry>& subsamples) override; + Status SubmitDecode(scoped_refptr<H265Picture> pic) override; + bool OutputPicture(scoped_refptr<H265Picture> pic) override; + void Reset() override; + bool IsChromaSamplingSupported(VideoChromaSampling format) override; + + private: + std::unique_ptr<MediaLog> media_log_; + + // Callbacks are called synchronously, which is always re-entrant. + DecodeCB decode_cb_; + OutputCB output_cb_; + + // Raw parameter set bytes that have been observed. + base::flat_map<int, std::vector<uint8_t>> seen_vps_data_; // IDs can be 0-16 + base::flat_map<int, std::vector<uint8_t>> seen_sps_data_; // IDs can be 0-15 + base::flat_map<int, std::vector<uint8_t>> seen_pps_data_; // IDs can be 0-63 + + // Raw parameter set bytes used to produce |active_format_|, so that they + // can be checked for changes. + std::vector<uint8_t> active_vps_data_; + std::vector<uint8_t> active_sps_data_; + std::vector<uint8_t> active_pps_data_; + + base::apple::ScopedCFTypeRef<CMFormatDescriptionRef> active_format_; + + // Accumulated slice data for the current frame. + std::vector<base::span<const uint8_t>> slice_nalu_data_; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +} // namespace media + +#endif // MEDIA_GPU_MAC_VIDEO_TOOLBOX_H265_ACCELERATOR_H_
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc b/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc new file mode 100644 index 0000000..06419de --- /dev/null +++ b/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc
@@ -0,0 +1,255 @@ +// 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 "media/gpu/mac/video_toolbox_h265_accelerator.h" + +#include <memory> + +#include "base/containers/span.h" +#include "media/base/media_util.h" +#include "media/gpu/codec_picture.h" +#include "media/video/h265_parser.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::ElementsAre; +using testing::SaveArg; + +namespace media { + +namespace { + +// Configuration from buck1080p60_hevc.mp4 +constexpr uint8_t kVPS0[] = {0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x03, 0x00, 0x7b, 0x95, 0x98, 0x09}; +constexpr uint8_t kSPS0[] = { + 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x7b, 0xa0, 0x03, 0xc0, 0x80, + 0x10, 0xe5, 0x96, 0x56, 0x69, 0x24, 0xca, 0xf0, 0x16, 0x9c, 0x20, + 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x07, 0x81}; +constexpr uint8_t kPPS0[] = {0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40}; + +// Configuration from bear-1280x720-hevc-10bit-hdr10.mp4 +constexpr uint8_t kVPS1[] = {0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x02, 0x20, + 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x03, 0x00, 0x5d, 0x95, 0x98, 0x09}; +constexpr uint8_t kSPS1[] = { + 0x42, 0x01, 0x01, 0x02, 0x20, 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x03, 0x00, 0x5d, 0xa0, 0x02, 0x80, 0x80, 0x2d, 0x13, + 0x65, 0x95, 0x9a, 0x49, 0x32, 0xbc, 0x05, 0xa8, 0x48, 0x80, 0x4f, 0x08, + 0x00, 0x00, 0x1f, 0x48, 0x00, 0x03, 0xa9, 0x80, 0x40}; +constexpr uint8_t kPPS1[] = {0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40}; + +constexpr uint8_t kSliceData[] = {0x02}; + +} // namespace + +class VideoToolboxH265AcceleratorTest : public testing::Test { + public: + VideoToolboxH265AcceleratorTest() = default; + ~VideoToolboxH265AcceleratorTest() override = default; + + protected: + MOCK_METHOD2(OnDecode, + void(base::apple::ScopedCFTypeRef<CMSampleBufferRef>, + scoped_refptr<CodecPicture>)); + MOCK_METHOD1(OnOutput, void(scoped_refptr<CodecPicture>)); + + std::unique_ptr<VideoToolboxH265Accelerator> accelerator_{ + std::make_unique<VideoToolboxH265Accelerator>( + std::make_unique<NullMediaLog>(), + base::BindRepeating(&VideoToolboxH265AcceleratorTest::OnDecode, + base::Unretained(this)), + base::BindRepeating(&VideoToolboxH265AcceleratorTest::OnOutput, + base::Unretained(this)))}; +}; + +TEST_F(VideoToolboxH265AcceleratorTest, Construct) {} + +TEST_F(VideoToolboxH265AcceleratorTest, DecodeOne) { + scoped_refptr<H265Picture> pic = accelerator_->CreateH265Picture(); + H265VPS vps; + H265SPS sps; + H265PPS pps; + H265SliceHeader slice_hdr; + H265Picture::Vector ref_pic_list; + std::vector<SubsampleEntry> subsamples; + + // Decode frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS0)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS0)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS0)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample)); + accelerator_->SubmitDecode(pic); + + // Verify sample. + CMBlockBufferRef buf = CMSampleBufferGetDataBuffer(sample); + std::vector<uint8_t> data(CMBlockBufferGetDataLength(buf)); + CMBlockBufferCopyDataBytes(buf, 0, CMBlockBufferGetDataLength(buf), + data.data()); + EXPECT_THAT(data, ElementsAre(0x00, 0x00, 0x00, 0x01, // length + 0x02 // kSliceData + )); + + // Check that OutputPicture() works. + EXPECT_CALL(*this, OnOutput(_)); + accelerator_->OutputPicture(pic); +} + +TEST_F(VideoToolboxH265AcceleratorTest, DecodeTwo) { + scoped_refptr<H265Picture> pic0 = accelerator_->CreateH265Picture(); + scoped_refptr<H265Picture> pic1 = accelerator_->CreateH265Picture(); + H265VPS vps; + H265SPS sps; + H265PPS pps; + H265SliceHeader slice_hdr; + H265Picture::Vector ref_pic_list; + std::vector<SubsampleEntry> subsamples; + + // First frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS0)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS0)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS0)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic0); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic0, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample0; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample0)); + accelerator_->SubmitDecode(pic0); + + // Second frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS0)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS0)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS0)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic1); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic1, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample1; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample1)); + accelerator_->SubmitDecode(pic1); + + // The two samples should have the same configuration. + EXPECT_EQ(CMSampleBufferGetFormatDescription(sample0), + CMSampleBufferGetFormatDescription(sample1)); +} + +TEST_F(VideoToolboxH265AcceleratorTest, DecodeTwo_Reset) { + scoped_refptr<H265Picture> pic0 = accelerator_->CreateH265Picture(); + scoped_refptr<H265Picture> pic1 = accelerator_->CreateH265Picture(); + H265VPS vps; + H265SPS sps; + H265PPS pps; + H265SliceHeader slice_hdr; + H265Picture::Vector ref_pic_list; + std::vector<SubsampleEntry> subsamples; + + // First frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS0)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS0)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS0)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic0); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic0, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample0; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample0)); + accelerator_->SubmitDecode(pic0); + + // Reset. + accelerator_->Reset(); + + // Second frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS0)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS0)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS0)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic1); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic1, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample1; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample1)); + accelerator_->SubmitDecode(pic1); + + // The two samples should have different configurations. + EXPECT_NE(CMSampleBufferGetFormatDescription(sample0), + CMSampleBufferGetFormatDescription(sample1)); +} + +TEST_F(VideoToolboxH265AcceleratorTest, DecodeTwo_ConfigChange) { + scoped_refptr<H265Picture> pic0 = accelerator_->CreateH265Picture(); + scoped_refptr<H265Picture> pic1 = accelerator_->CreateH265Picture(); + H265VPS vps; + H265SPS sps; + H265PPS pps; + H265SliceHeader slice_hdr; + H265Picture::Vector ref_pic_list; + std::vector<SubsampleEntry> subsamples; + + // First frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS0)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS0)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS0)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic0); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic0, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample0; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample0)); + accelerator_->SubmitDecode(pic0); + + // Second frame. + accelerator_->ProcessVPS(&vps, base::make_span(kVPS1)); + accelerator_->ProcessSPS(&sps, base::make_span(kSPS1)); + accelerator_->ProcessPPS(&pps, base::make_span(kPPS1)); + accelerator_->SubmitFrameMetadata(&sps, &pps, &slice_hdr, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, + pic1); + accelerator_->SubmitSlice(&sps, &pps, &slice_hdr, ref_pic_list, ref_pic_list, + ref_pic_list, ref_pic_list, ref_pic_list, pic1, + kSliceData, sizeof(kSliceData), subsamples); + + // Save the resulting sample. + base::apple::ScopedCFTypeRef<CMSampleBufferRef> sample1; + EXPECT_CALL(*this, OnDecode(_, _)).WillOnce(SaveArg<0>(&sample1)); + accelerator_->SubmitDecode(pic1); + + // The two samples should have different configurations. + EXPECT_NE(CMSampleBufferGetFormatDescription(sample0), + CMSampleBufferGetFormatDescription(sample1)); +} + +} // namespace media
diff --git a/media/gpu/mac/video_toolbox_video_decoder.cc b/media/gpu/mac/video_toolbox_video_decoder.cc index fca8dd5..94bdab6 100644 --- a/media/gpu/mac/video_toolbox_video_decoder.cc +++ b/media/gpu/mac/video_toolbox_video_decoder.cc
@@ -11,6 +11,7 @@ #include <utility> #include "base/apple/scoped_cftyperef.h" +#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" @@ -18,6 +19,7 @@ #include "base/task/bind_post_task.h" #include "media/base/decoder_status.h" #include "media/base/media_log.h" +#include "media/base/media_switches.h" #include "media/base/video_frame.h" #include "media/gpu/accelerated_video_decoder.h" #include "media/gpu/h264_decoder.h" @@ -27,6 +29,11 @@ #include "media/gpu/vp9_decoder.h" #include "ui/gfx/geometry/size.h" +#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) +#include "media/gpu/h265_decoder.h" +#include "media/gpu/mac/video_toolbox_h265_accelerator.h" +#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) + namespace media { namespace { @@ -49,6 +56,19 @@ return initialized; } +#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) +bool SupportsHEVC() { + // HEVC should be supported with 10.13+, but per crbug.com/1300444#c9 it is + // only reliable on Intel hardware with 11+. + if (base::FeatureList::IsEnabled(media::kPlatformHEVCDecoderSupport)) { + if (__builtin_available(macOS 11.0, *)) { + return true; + } + } + return false; +} +#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) + } // namespace VideoToolboxVideoDecoder::VideoToolboxVideoDecoder( @@ -169,6 +189,16 @@ config.profile(), config.color_space_info()); break; +#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) + case VideoCodec::kHEVC: + accelerator_ = std::make_unique<H265Decoder>( + std::make_unique<VideoToolboxH265Accelerator>( + media_log_->Clone(), std::move(accelerator_decode_cb), + std::move(accelerator_output_cb)), + config.profile(), config.color_space_info()); + break; +#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) + default: task_runner_->PostTask( FROM_HERE, base::BindOnce(std::move(init_cb), @@ -388,13 +418,15 @@ // TODO(crbug.com/1331597): Test support for other H.264 profiles. // TODO(crbug.com/1331597): Exclude resolutions that are not accelerated. // TODO(crbug.com/1331597): Check if higher resolutions are supported. - supported.emplace_back( - /*profile_min=*/H264PROFILE_BASELINE, - /*profile_max=*/H264PROFILE_HIGH, - /*coded_size_min=*/gfx::Size(16, 16), - /*coded_size_max=*/gfx::Size(4096, 4096), - /*allow_encrypted=*/false, - /*require_encrypted=*/false); + if (!gpu_workarounds.disable_accelerated_h264_decode) { + supported.emplace_back( + /*profile_min=*/H264PROFILE_BASELINE, + /*profile_max=*/H264PROFILE_HIGH, + /*coded_size_min=*/gfx::Size(16, 16), + /*coded_size_max=*/gfx::Size(4096, 4096), + /*allow_encrypted=*/false, + /*require_encrypted=*/false); + } if (!gpu_workarounds.disable_accelerated_vp9_decode && SupportsVP9()) { supported.emplace_back( @@ -404,14 +436,35 @@ /*coded_size_max=*/gfx::Size(4096, 4096), /*allow_encrypted=*/false, /*require_encrypted=*/false); + if (!gpu_workarounds.disable_accelerated_vp9_profile2_decode) { + supported.emplace_back( + /*profile_min=*/VP9PROFILE_PROFILE2, + /*profile_max=*/VP9PROFILE_PROFILE2, + /*coded_size_min=*/gfx::Size(16, 16), + /*coded_size_max=*/gfx::Size(4096, 4096), + /*allow_encrypted=*/false, + /*require_encrypted=*/false); + } + } + +#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) + if (!gpu_workarounds.disable_accelerated_hevc_decode && SupportsHEVC()) { supported.emplace_back( - /*profile_min=*/VP9PROFILE_PROFILE2, - /*profile_max=*/VP9PROFILE_PROFILE2, + /*profile_min=*/HEVCPROFILE_MIN, + /*profile_max=*/HEVCPROFILE_MAX, /*coded_size_min=*/gfx::Size(16, 16), - /*coded_size_max=*/gfx::Size(4096, 4096), + /*coded_size_max=*/gfx::Size(8192, 8192), + /*allow_encrypted=*/false, + /*require_encrypted=*/false); + supported.emplace_back( + /*profile_min=*/HEVCPROFILE_REXT, + /*profile_max=*/HEVCPROFILE_REXT, + /*coded_size_min=*/gfx::Size(16, 16), + /*coded_size_max=*/gfx::Size(8192, 8192), /*allow_encrypted=*/false, /*require_encrypted=*/false); } +#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) return supported; }
diff --git a/media/mojo/services/mojo_video_decoder_service.h b/media/mojo/services/mojo_video_decoder_service.h index 13d8cd0a..96c0d1b 100644 --- a/media/mojo/services/mojo_video_decoder_service.h +++ b/media/mojo/services/mojo_video_decoder_service.h
@@ -101,10 +101,11 @@ std::string codec_string_; // Decoder factory. - raw_ptr<MojoMediaClient> mojo_media_client_; + raw_ptr<MojoMediaClient, LeakedDanglingUntriaged> mojo_media_client_; // A helper object required to get the CDM from a CDM ID. - raw_ptr<MojoCdmServiceContext> mojo_cdm_service_context_ = nullptr; + raw_ptr<MojoCdmServiceContext, LeakedDanglingUntriaged> + mojo_cdm_service_context_ = nullptr; // Channel for sending async messages to the client. mojo::AssociatedRemote<mojom::VideoDecoderClient> client_;
diff --git a/remoting/host/file_transfer/file_chooser_chromeos.cc b/remoting/host/file_transfer/file_chooser_chromeos.cc index 66ffad9..3287096 100644 --- a/remoting/host/file_transfer/file_chooser_chromeos.cc +++ b/remoting/host/file_transfer/file_chooser_chromeos.cc
@@ -52,7 +52,7 @@ void Cleanup(); scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - const raw_ref<AshProxy, ExperimentalAsh> ash_; + const raw_ref<AshProxy, LeakedDanglingUntriaged | ExperimentalAsh> ash_; FileChooser::ResultCallback callback_; };
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 916a391d..066120f 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -7638,6 +7638,54 @@ } ] }, + "android-chrome-pie-x86-wpt-android-specific": { + "isolated_scripts": [ + { + "args": [ + "--avd-config=../../tools/android/avd/proto/generic_android28.textpb" + ], + "isolate_name": "chrome_public_wpt", + "merge": { + "args": [ + "--verbose", + "--test-list", + "//third_party/blink/web_tests/TestLists/Default.txt" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "wpt_tests_suite", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "results_handler": "layout tests", + "swarming": { + "dimensions": { + "cores": "8", + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "os": "Ubuntu-22.04", + "pool": "chromium.tests.avd" + }, + "named_caches": [ + { + "name": "generic_android28", + "path": ".android_emulator/generic_android28" + } + ], + "optional_dimensions": { + "60": { + "caches": "generic_android28" + } + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 15 + }, + "test_id_prefix": "ninja://chrome/android:chrome_public_wpt/" + } + ] + }, "android-chrome-pie-x86-wpt-fyi-rel": { "isolated_scripts": [ {
diff --git a/testing/buildbot/chromium.angle.json b/testing/buildbot/chromium.angle.json index 4a705ccc..1ab48a8 100644 --- a/testing/buildbot/chromium.angle.json +++ b/testing/buildbot/chromium.angle.json
@@ -61,7 +61,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_profile_data": true, @@ -90,7 +90,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -115,7 +115,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_profile_data": true, @@ -144,7 +144,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -169,7 +169,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_profile_data": true, @@ -198,7 +198,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -223,7 +223,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_profile_data": true, @@ -252,7 +252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 8de16f8..b1d8b9a 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -4886,9 +4886,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4898,8 +4898,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -5033,9 +5033,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5045,8 +5045,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -5165,9 +5165,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5177,8 +5177,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index 332e8cf0..7675fdf 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -2042,7 +2042,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -2068,7 +2068,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -2110,7 +2110,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -2138,7 +2138,7 @@ "expiration": 21600, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" } ],
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 6d6a35e..01700f3 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -9111,7 +9111,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -9138,7 +9138,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9161,7 +9161,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -9188,7 +9188,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9211,7 +9211,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -9238,7 +9238,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9261,7 +9261,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -9288,7 +9288,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9311,7 +9311,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9338,7 +9338,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9361,7 +9361,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9388,7 +9388,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9411,7 +9411,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9438,7 +9438,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9461,7 +9461,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9488,7 +9488,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9511,7 +9511,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9538,7 +9538,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9561,7 +9561,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9588,7 +9588,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9611,7 +9611,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9638,7 +9638,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9661,7 +9661,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9688,7 +9688,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9711,7 +9711,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9738,7 +9738,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9761,7 +9761,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9788,7 +9788,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9811,7 +9811,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -9838,7 +9838,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9861,7 +9861,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -9888,7 +9888,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9911,7 +9911,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -9938,7 +9938,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9961,7 +9961,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -9988,7 +9988,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10011,7 +10011,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -10038,7 +10038,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10061,7 +10061,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -10088,7 +10088,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10111,7 +10111,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -10138,7 +10138,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10161,7 +10161,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -10188,7 +10188,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10211,7 +10211,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -10238,7 +10238,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10261,7 +10261,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10288,7 +10288,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10311,7 +10311,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10338,7 +10338,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10361,7 +10361,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10388,7 +10388,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10411,7 +10411,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10438,7 +10438,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10461,7 +10461,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10488,7 +10488,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10511,7 +10511,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10538,7 +10538,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10561,7 +10561,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10588,7 +10588,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10611,7 +10611,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10638,7 +10638,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10661,7 +10661,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10688,7 +10688,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10711,7 +10711,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10738,7 +10738,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10761,7 +10761,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -10788,7 +10788,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10811,7 +10811,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -10838,7 +10838,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10861,7 +10861,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -10888,7 +10888,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10911,7 +10911,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -10938,7 +10938,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10961,7 +10961,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -10988,7 +10988,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11011,7 +11011,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -11038,7 +11038,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11061,7 +11061,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -11088,7 +11088,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11111,7 +11111,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -11138,7 +11138,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11161,7 +11161,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -11188,7 +11188,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11211,7 +11211,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11238,7 +11238,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11261,7 +11261,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11288,7 +11288,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11311,7 +11311,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11338,7 +11338,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11361,7 +11361,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11388,7 +11388,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11411,7 +11411,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11438,7 +11438,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11461,7 +11461,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11488,7 +11488,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11511,7 +11511,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11538,7 +11538,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11561,7 +11561,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11588,7 +11588,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11611,7 +11611,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11638,7 +11638,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11661,7 +11661,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11688,7 +11688,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11711,7 +11711,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -11738,7 +11738,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11761,7 +11761,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -11788,7 +11788,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11811,7 +11811,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -11838,7 +11838,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11861,7 +11861,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -11888,7 +11888,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11911,7 +11911,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -11938,7 +11938,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11961,7 +11961,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -11989,7 +11989,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12012,7 +12012,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12040,7 +12040,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12063,7 +12063,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12091,7 +12091,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12114,7 +12114,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12142,7 +12142,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12165,7 +12165,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12193,7 +12193,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12216,7 +12216,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12244,7 +12244,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12267,7 +12267,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12295,7 +12295,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12318,7 +12318,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12346,7 +12346,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12369,7 +12369,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12399,7 +12399,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12423,7 +12423,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12453,7 +12453,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12477,7 +12477,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12507,7 +12507,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12531,7 +12531,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12561,7 +12561,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12585,7 +12585,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12615,7 +12615,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12639,7 +12639,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12669,7 +12669,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12693,7 +12693,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12723,7 +12723,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12747,7 +12747,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12777,7 +12777,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12801,7 +12801,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12831,7 +12831,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12855,7 +12855,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12885,7 +12885,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12909,7 +12909,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12939,7 +12939,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12963,7 +12963,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12993,7 +12993,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13017,7 +13017,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13047,7 +13047,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13071,7 +13071,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13101,7 +13101,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13125,7 +13125,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13155,7 +13155,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13179,7 +13179,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13209,7 +13209,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13233,7 +13233,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13261,7 +13261,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13285,7 +13285,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13313,7 +13313,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13337,7 +13337,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13365,7 +13365,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13389,7 +13389,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13417,7 +13417,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13441,7 +13441,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13469,7 +13469,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13493,7 +13493,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13521,7 +13521,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13545,7 +13545,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13573,7 +13573,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13597,7 +13597,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13625,7 +13625,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13649,7 +13649,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13677,7 +13677,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13700,7 +13700,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13728,7 +13728,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13751,7 +13751,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13779,7 +13779,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13802,7 +13802,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13830,7 +13830,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13853,7 +13853,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13881,7 +13881,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13904,7 +13904,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13932,7 +13932,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13955,7 +13955,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13983,7 +13983,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14006,7 +14006,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14034,7 +14034,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14057,7 +14057,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14087,7 +14087,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14111,7 +14111,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14141,7 +14141,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14165,7 +14165,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14195,7 +14195,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14219,7 +14219,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14249,7 +14249,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14273,7 +14273,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14303,7 +14303,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14327,7 +14327,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14357,7 +14357,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14381,7 +14381,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14411,7 +14411,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14435,7 +14435,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -14465,7 +14465,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14489,7 +14489,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14516,7 +14516,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14539,7 +14539,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14566,7 +14566,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14589,7 +14589,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14616,7 +14616,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14639,7 +14639,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14666,7 +14666,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14689,7 +14689,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14716,7 +14716,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14739,7 +14739,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14766,7 +14766,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14789,7 +14789,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14816,7 +14816,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14839,7 +14839,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14866,7 +14866,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14889,7 +14889,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14916,7 +14916,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14939,7 +14939,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14966,7 +14966,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14989,7 +14989,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -15016,7 +15016,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15039,7 +15039,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15067,7 +15067,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15091,7 +15091,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15119,7 +15119,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15143,7 +15143,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15171,7 +15171,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15195,7 +15195,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15223,7 +15223,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15247,7 +15247,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15275,7 +15275,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15299,7 +15299,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15327,7 +15327,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15351,7 +15351,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15379,7 +15379,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15403,7 +15403,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15431,7 +15431,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15455,7 +15455,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -15482,7 +15482,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15505,7 +15505,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -15532,7 +15532,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15555,7 +15555,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -15582,7 +15582,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15605,7 +15605,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -15632,7 +15632,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15655,7 +15655,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -15682,7 +15682,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15706,7 +15706,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -15733,7 +15733,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15757,7 +15757,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -15784,7 +15784,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15808,7 +15808,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -15835,7 +15835,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15859,7 +15859,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -15886,7 +15886,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15909,7 +15909,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -15936,7 +15936,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15959,7 +15959,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -15986,7 +15986,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16009,7 +16009,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -16036,7 +16036,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16059,7 +16059,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16087,7 +16087,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16110,7 +16110,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16138,7 +16138,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16161,7 +16161,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16189,7 +16189,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16212,7 +16212,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16240,7 +16240,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16263,7 +16263,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16291,7 +16291,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16314,7 +16314,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16342,7 +16342,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16365,7 +16365,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16393,7 +16393,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16416,7 +16416,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16444,7 +16444,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16467,7 +16467,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -16494,7 +16494,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16517,7 +16517,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -16544,7 +16544,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16567,7 +16567,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -16594,7 +16594,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16617,7 +16617,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -16644,7 +16644,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16667,7 +16667,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16694,7 +16694,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16717,7 +16717,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16744,7 +16744,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16767,7 +16767,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16794,7 +16794,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16817,7 +16817,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16844,7 +16844,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16867,7 +16867,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16894,7 +16894,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16917,7 +16917,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16944,7 +16944,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16967,7 +16967,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16994,7 +16994,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17017,7 +17017,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -17044,7 +17044,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17067,7 +17067,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -17094,7 +17094,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17117,7 +17117,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -17144,7 +17144,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17167,7 +17167,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -17194,7 +17194,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17217,7 +17217,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17245,7 +17245,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17268,7 +17268,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17296,7 +17296,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17319,7 +17319,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17347,7 +17347,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17370,7 +17370,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17398,7 +17398,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17421,7 +17421,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17449,7 +17449,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17472,7 +17472,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17500,7 +17500,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17523,7 +17523,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17551,7 +17551,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17574,7 +17574,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -17602,7 +17602,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17625,7 +17625,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17652,7 +17652,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17675,7 +17675,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17702,7 +17702,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17725,7 +17725,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17752,7 +17752,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17775,7 +17775,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17802,7 +17802,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17825,7 +17825,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17852,7 +17852,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17875,7 +17875,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17902,7 +17902,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17925,7 +17925,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -17952,7 +17952,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17975,7 +17975,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -18002,7 +18002,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18025,7 +18025,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -18052,7 +18052,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18075,7 +18075,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -18102,7 +18102,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18125,7 +18125,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -18152,7 +18152,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18175,7 +18175,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18202,7 +18202,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18225,7 +18225,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18252,7 +18252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18275,7 +18275,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18302,7 +18302,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18325,7 +18325,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18352,7 +18352,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18375,7 +18375,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18402,7 +18402,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18425,7 +18425,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18452,7 +18452,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18475,7 +18475,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18502,7 +18502,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18525,7 +18525,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18552,7 +18552,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18575,7 +18575,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18602,7 +18602,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18625,7 +18625,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18652,7 +18652,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18675,7 +18675,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -18702,7 +18702,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18725,7 +18725,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -18752,7 +18752,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18775,7 +18775,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -18802,7 +18802,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18825,7 +18825,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -18852,7 +18852,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18875,7 +18875,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -18902,7 +18902,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18925,7 +18925,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -18952,7 +18952,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18975,7 +18975,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -19002,7 +19002,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19025,7 +19025,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -19052,7 +19052,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19075,7 +19075,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -19102,7 +19102,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19125,7 +19125,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -19152,7 +19152,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19175,7 +19175,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -19202,7 +19202,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19225,7 +19225,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -19252,7 +19252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19275,7 +19275,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -19302,7 +19302,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19325,7 +19325,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -19352,7 +19352,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19375,7 +19375,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -19402,7 +19402,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19425,7 +19425,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -19452,7 +19452,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19475,7 +19475,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -19502,7 +19502,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19525,7 +19525,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -19552,7 +19552,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19575,7 +19575,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -19602,7 +19602,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19625,7 +19625,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -19652,7 +19652,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19675,7 +19675,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -19702,7 +19702,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19725,7 +19725,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -19752,7 +19752,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19775,7 +19775,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -19802,7 +19802,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19825,7 +19825,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -19852,7 +19852,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19875,7 +19875,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -19902,7 +19902,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19925,7 +19925,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -19952,7 +19952,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19975,7 +19975,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -20002,7 +20002,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20025,7 +20025,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -20052,7 +20052,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20075,7 +20075,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -20102,7 +20102,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20125,7 +20125,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -20152,7 +20152,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20175,7 +20175,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -20202,7 +20202,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20225,7 +20225,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -20252,7 +20252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20275,7 +20275,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -20302,7 +20302,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20325,7 +20325,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -20352,7 +20352,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20375,7 +20375,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -20402,7 +20402,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20425,7 +20425,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20452,7 +20452,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20475,7 +20475,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20502,7 +20502,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20525,7 +20525,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20552,7 +20552,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20575,7 +20575,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20602,7 +20602,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20625,7 +20625,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20652,7 +20652,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20675,7 +20675,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20702,7 +20702,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20725,7 +20725,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20752,7 +20752,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20775,7 +20775,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20802,7 +20802,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20825,7 +20825,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20852,7 +20852,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20875,7 +20875,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20902,7 +20902,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20925,7 +20925,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -20952,7 +20952,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20975,7 +20975,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -21002,7 +21002,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21025,7 +21025,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -21052,7 +21052,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21075,7 +21075,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -21102,7 +21102,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21125,7 +21125,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -21152,7 +21152,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -25056,9 +25056,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25068,8 +25068,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -25203,9 +25203,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25215,8 +25215,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -25335,9 +25335,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25347,8 +25347,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 042447ce..d1c2abd 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -6375,7 +6375,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6404,7 +6404,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6426,7 +6426,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6455,7 +6455,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6477,7 +6477,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6506,7 +6506,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6529,7 +6529,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6558,7 +6558,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6581,7 +6581,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6610,7 +6610,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6633,7 +6633,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6662,7 +6662,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6685,7 +6685,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6714,7 +6714,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6737,7 +6737,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6766,7 +6766,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6789,7 +6789,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6818,7 +6818,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6840,7 +6840,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6869,7 +6869,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6891,7 +6891,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6920,7 +6920,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6943,7 +6943,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -6972,7 +6972,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -6995,7 +6995,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -7024,7 +7024,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7047,7 +7047,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -7076,7 +7076,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7099,7 +7099,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -7128,7 +7128,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7150,7 +7150,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -7179,7 +7179,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7201,7 +7201,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -7230,7 +7230,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7252,7 +7252,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--extra-app-args=--disable-field-trial-config" @@ -7281,7 +7281,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7310,7 +7310,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -7336,7 +7336,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7358,7 +7358,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -7384,7 +7384,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7406,7 +7406,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7432,7 +7432,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7454,7 +7454,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7480,7 +7480,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7502,7 +7502,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7528,7 +7528,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7550,7 +7550,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7576,7 +7576,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7598,7 +7598,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7624,7 +7624,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7646,7 +7646,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7672,7 +7672,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7694,7 +7694,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7720,7 +7720,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7742,7 +7742,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7768,7 +7768,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7790,7 +7790,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -7816,7 +7816,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7838,7 +7838,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -7864,7 +7864,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7886,7 +7886,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -7912,7 +7912,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7934,7 +7934,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -7960,7 +7960,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7982,7 +7982,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8008,7 +8008,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8030,7 +8030,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8056,7 +8056,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8078,7 +8078,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8104,7 +8104,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8126,7 +8126,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8152,7 +8152,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8174,7 +8174,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8200,7 +8200,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8222,7 +8222,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8248,7 +8248,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8270,7 +8270,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8296,7 +8296,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8318,7 +8318,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8344,7 +8344,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8366,7 +8366,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -8392,7 +8392,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8414,7 +8414,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -8440,7 +8440,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8462,7 +8462,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -8488,7 +8488,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8510,7 +8510,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -8536,7 +8536,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8558,7 +8558,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8584,7 +8584,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8606,7 +8606,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8632,7 +8632,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8654,7 +8654,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8680,7 +8680,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8702,7 +8702,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8728,7 +8728,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8750,7 +8750,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8776,7 +8776,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8798,7 +8798,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8824,7 +8824,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8846,7 +8846,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8872,7 +8872,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8894,7 +8894,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8920,7 +8920,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8942,7 +8942,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -8968,7 +8968,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8990,7 +8990,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -9016,7 +9016,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9038,7 +9038,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9067,7 +9067,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9089,7 +9089,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9118,7 +9118,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9134,64 +9134,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPad (10th generation)", "--version", "16.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9220,7 +9169,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9243,7 +9192,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9272,7 +9221,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9295,7 +9244,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9324,7 +9273,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9347,7 +9296,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9376,7 +9325,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9399,7 +9348,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9428,7 +9377,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9451,7 +9400,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9480,7 +9429,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9503,7 +9452,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9532,7 +9481,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9555,7 +9504,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9584,7 +9533,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9607,7 +9556,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9636,7 +9585,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9659,7 +9608,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9688,7 +9637,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9705,65 +9654,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPad Air (5th generation)", "--version", "17.0", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9792,7 +9689,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9815,7 +9712,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9844,7 +9741,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9861,65 +9758,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPad Air (5th generation)", "--version", "17.0", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9948,7 +9793,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9970,7 +9815,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -9999,7 +9844,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10015,64 +9860,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPad Air (5th generation)", "--version", "17.0", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -10101,7 +9895,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10124,7 +9918,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -10153,7 +9947,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10170,65 +9964,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPad Air (5th generation)", "--version", "16.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10254,7 +9996,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10276,7 +10018,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10302,7 +10044,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10324,7 +10066,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10350,7 +10092,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10372,7 +10114,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10398,7 +10140,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10420,7 +10162,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10446,7 +10188,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10468,7 +10210,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10494,7 +10236,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10516,7 +10258,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10542,7 +10284,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10564,7 +10306,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -10590,7 +10332,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10612,7 +10354,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -10641,7 +10383,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10664,7 +10406,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -10693,7 +10435,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10710,65 +10452,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPhone 14", "--version", "16.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -10794,7 +10484,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10816,7 +10506,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -10842,7 +10532,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10864,7 +10554,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -10890,7 +10580,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10913,7 +10603,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -10939,7 +10629,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10962,7 +10652,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -10988,7 +10678,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11010,7 +10700,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -11036,7 +10726,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11058,7 +10748,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11087,7 +10777,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11109,7 +10799,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11138,7 +10828,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11154,64 +10844,13 @@ { "args": [ "--platform", - "iPhone 14 Pro Max", - "--version", - "17.0", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "15a5209g", - "--xctest", - "--xcode-parallelization", - "--record-video", - "failed_only" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module iPhone 14 Pro Max 17.0", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb" - } - ], - "dimensions": { - "cpu": "arm64", - "os": "Mac-13.4" - }, - "named_caches": [ - { - "name": "xcode_ios_15a5209g", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/", - "variant_id": "iPhone 14 Pro Max 17.0" - }, - { - "args": [ - "--platform", "iPhone 14", "--version", "16.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -11237,7 +10876,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11259,7 +10898,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -11285,7 +10924,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11307,7 +10946,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11333,7 +10972,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11355,7 +10994,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11381,7 +11020,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11403,7 +11042,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11429,7 +11068,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11451,7 +11090,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11477,7 +11116,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11499,7 +11138,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11525,7 +11164,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11547,7 +11186,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11573,7 +11212,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11595,7 +11234,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11621,7 +11260,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11643,7 +11282,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -11669,7 +11308,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11691,7 +11330,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11720,7 +11359,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11742,7 +11381,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11771,7 +11410,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11793,7 +11432,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11822,7 +11461,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11844,7 +11483,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11873,7 +11512,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11895,7 +11534,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11924,7 +11563,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11946,7 +11585,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -11975,7 +11614,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11997,7 +11636,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -12026,7 +11665,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12048,7 +11687,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -12077,7 +11716,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12099,7 +11738,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12125,7 +11764,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12147,7 +11786,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12173,7 +11812,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12195,7 +11834,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12221,7 +11860,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12243,7 +11882,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12269,7 +11908,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12291,7 +11930,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12317,7 +11956,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12339,7 +11978,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12365,7 +12004,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12387,7 +12026,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12413,7 +12052,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12435,7 +12074,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -12461,7 +12100,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12483,7 +12122,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12509,7 +12148,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12531,7 +12170,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12557,7 +12196,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12579,7 +12218,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12605,7 +12244,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12627,7 +12266,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12653,7 +12292,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12675,7 +12314,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12701,7 +12340,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12723,7 +12362,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12749,7 +12388,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12771,7 +12410,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12797,7 +12436,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12819,7 +12458,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -12845,7 +12484,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12867,7 +12506,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -12893,7 +12532,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12915,7 +12554,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -12941,7 +12580,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12963,7 +12602,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -12989,7 +12628,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13011,7 +12650,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -13037,7 +12676,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13059,7 +12698,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -13085,7 +12724,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13107,7 +12746,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -13133,7 +12772,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13155,7 +12794,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -13181,7 +12820,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13203,7 +12842,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -13229,7 +12868,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13251,7 +12890,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -13277,7 +12916,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13299,7 +12938,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -13325,7 +12964,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13347,7 +12986,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -13373,7 +13012,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13395,7 +13034,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -13421,7 +13060,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13443,7 +13082,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13469,7 +13108,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13491,7 +13130,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13517,7 +13156,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13539,7 +13178,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13565,7 +13204,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13587,7 +13226,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13613,7 +13252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13635,7 +13274,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13661,7 +13300,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13683,7 +13322,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13709,7 +13348,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13731,7 +13370,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13757,7 +13396,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13779,7 +13418,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -13805,7 +13444,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13827,7 +13466,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -13853,7 +13492,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13875,7 +13514,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -13901,7 +13540,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13923,7 +13562,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -13949,7 +13588,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13971,7 +13610,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -13997,7 +13636,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14019,7 +13658,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -14045,7 +13684,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14067,7 +13706,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -14093,7 +13732,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14115,7 +13754,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -14141,7 +13780,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14163,7 +13802,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -14189,7 +13828,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14211,7 +13850,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -14237,7 +13876,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14259,7 +13898,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -14285,7 +13924,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14307,7 +13946,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -14333,7 +13972,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14355,7 +13994,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -14381,7 +14020,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14407,7 +14046,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "cronet_test", @@ -14433,7 +14072,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14459,7 +14098,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "cronet_test", @@ -14485,7 +14124,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14511,7 +14150,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -14537,7 +14176,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14559,7 +14198,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -14585,7 +14224,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14607,7 +14246,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -14633,7 +14272,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14655,7 +14294,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -14681,7 +14320,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14703,7 +14342,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -14729,7 +14368,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14751,7 +14390,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -14777,7 +14416,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14799,7 +14438,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -14825,7 +14464,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14847,7 +14486,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -14873,7 +14512,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14895,7 +14534,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -14921,7 +14560,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14943,7 +14582,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -14969,7 +14608,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14991,7 +14630,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -15017,7 +14656,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15039,7 +14678,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -15065,7 +14704,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15087,7 +14726,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -15113,7 +14752,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15135,7 +14774,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -15161,7 +14800,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15183,7 +14822,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -15209,7 +14848,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15231,7 +14870,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -15257,7 +14896,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15279,7 +14918,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -15305,7 +14944,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15327,7 +14966,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -15353,7 +14992,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15375,7 +15014,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15402,7 +15041,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15424,7 +15063,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15451,7 +15090,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15473,7 +15112,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15500,7 +15139,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15523,7 +15162,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15550,7 +15189,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15573,7 +15212,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15600,7 +15239,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15623,7 +15262,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15650,7 +15289,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15673,7 +15312,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15700,7 +15339,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15723,7 +15362,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15750,7 +15389,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15773,7 +15412,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15800,7 +15439,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15822,7 +15461,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15849,7 +15488,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15871,7 +15510,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15898,7 +15537,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15921,7 +15560,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15948,7 +15587,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15971,7 +15610,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -15997,7 +15636,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16019,7 +15658,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -16045,7 +15684,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16067,7 +15706,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16094,7 +15733,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16117,7 +15756,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16144,7 +15783,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16167,7 +15806,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -16193,7 +15832,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16215,7 +15854,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -16241,7 +15880,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16263,7 +15902,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -16289,7 +15928,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16312,7 +15951,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -16338,7 +15977,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16361,7 +16000,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -16387,7 +16026,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16409,7 +16048,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -16435,7 +16074,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16457,7 +16096,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16484,7 +16123,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16506,7 +16145,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16533,7 +16172,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16555,7 +16194,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -16581,7 +16220,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16603,7 +16242,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -16629,7 +16268,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16651,7 +16290,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16677,7 +16316,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16699,7 +16338,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -16725,7 +16364,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16747,7 +16386,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16774,7 +16413,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16796,7 +16435,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -16823,7 +16462,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16845,7 +16484,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -16871,7 +16510,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16893,7 +16532,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -16919,7 +16558,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16941,7 +16580,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -16967,7 +16606,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16989,7 +16628,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -17015,7 +16654,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17037,7 +16676,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -17063,7 +16702,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17085,7 +16724,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -17111,7 +16750,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17133,7 +16772,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -17159,7 +16798,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17181,7 +16820,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -17207,7 +16846,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17229,7 +16868,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -17255,7 +16894,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17277,7 +16916,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -17303,7 +16942,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17325,7 +16964,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -17351,7 +16990,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17373,7 +17012,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -17399,7 +17038,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17421,7 +17060,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -17447,7 +17086,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17469,7 +17108,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -17495,7 +17134,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17517,7 +17156,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -17543,7 +17182,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17565,7 +17204,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -17591,7 +17230,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17613,7 +17252,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -17639,7 +17278,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17661,7 +17300,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -17687,7 +17326,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17715,7 +17354,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -17741,7 +17380,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17765,7 +17404,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -17791,7 +17430,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17815,7 +17454,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -17841,7 +17480,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17865,7 +17504,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -17891,7 +17530,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17915,7 +17554,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17941,7 +17580,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17965,7 +17604,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17991,7 +17630,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18015,7 +17654,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -18041,7 +17680,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18065,7 +17704,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -18091,7 +17730,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18115,7 +17754,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -18141,7 +17780,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18165,7 +17804,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -18191,7 +17830,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18215,7 +17854,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -18241,7 +17880,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18265,7 +17904,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -18291,7 +17930,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18315,7 +17954,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -18341,7 +17980,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18365,7 +18004,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -18391,7 +18030,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18415,7 +18054,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -18441,7 +18080,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18465,7 +18104,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -18491,7 +18130,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18515,7 +18154,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -18541,7 +18180,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18565,7 +18204,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -18591,7 +18230,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18615,7 +18254,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -18641,7 +18280,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18665,7 +18304,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -18691,7 +18330,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18715,7 +18354,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -18741,7 +18380,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18765,7 +18404,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -18791,7 +18430,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18815,7 +18454,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -18841,7 +18480,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18865,7 +18504,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -18891,7 +18530,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18915,7 +18554,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -18941,7 +18580,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18965,7 +18604,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -18991,7 +18630,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19015,7 +18654,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -19041,7 +18680,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19065,7 +18704,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -19091,7 +18730,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19115,7 +18754,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -19141,7 +18780,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19165,7 +18804,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -19191,7 +18830,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19215,7 +18854,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -19241,7 +18880,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19265,7 +18904,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -19291,7 +18930,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19315,7 +18954,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -19341,7 +18980,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19365,7 +19004,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -19391,7 +19030,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19415,7 +19054,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -19441,7 +19080,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19465,7 +19104,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -19491,7 +19130,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19515,7 +19154,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19542,7 +19181,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19566,7 +19205,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19593,7 +19232,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19617,7 +19256,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19644,7 +19283,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19668,7 +19307,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19695,7 +19334,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19719,7 +19358,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -19748,7 +19387,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19773,7 +19412,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -19802,7 +19441,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19827,7 +19466,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -19856,7 +19495,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19881,7 +19520,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -19910,7 +19549,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19935,7 +19574,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19962,7 +19601,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19987,7 +19626,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20014,7 +19653,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20039,7 +19678,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20066,7 +19705,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20091,7 +19730,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20118,7 +19757,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20143,7 +19782,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20170,7 +19809,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20195,7 +19834,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20222,7 +19861,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20247,7 +19886,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20274,7 +19913,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20299,7 +19938,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20326,7 +19965,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20351,7 +19990,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20378,7 +20017,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20402,7 +20041,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20429,7 +20068,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20453,7 +20092,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20480,7 +20119,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20504,7 +20143,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20531,7 +20170,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20555,7 +20194,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20582,7 +20221,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20607,7 +20246,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20634,7 +20273,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20659,7 +20298,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20686,7 +20325,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20711,7 +20350,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20738,7 +20377,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20763,7 +20402,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -20789,7 +20428,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20813,7 +20452,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -20839,7 +20478,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20863,7 +20502,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -20889,7 +20528,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20913,7 +20552,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -20939,7 +20578,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20963,7 +20602,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -20990,7 +20629,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21015,7 +20654,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21042,7 +20681,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21067,7 +20706,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21094,7 +20733,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21119,7 +20758,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21146,7 +20785,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21171,7 +20810,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -21197,7 +20836,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21221,7 +20860,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -21247,7 +20886,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21271,7 +20910,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -21297,7 +20936,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21321,7 +20960,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -21347,7 +20986,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21371,7 +21010,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -21397,7 +21036,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21422,7 +21061,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -21448,7 +21087,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21473,7 +21112,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -21499,7 +21138,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21524,7 +21163,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -21550,7 +21189,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21575,7 +21214,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -21601,7 +21240,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21625,7 +21264,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -21651,7 +21290,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21675,7 +21314,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -21701,7 +21340,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21725,7 +21364,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -21751,7 +21390,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21775,7 +21414,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21802,7 +21441,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21826,7 +21465,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21853,7 +21492,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21877,7 +21516,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21904,7 +21543,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21928,7 +21567,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -21955,7 +21594,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21979,7 +21618,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -22005,7 +21644,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22029,7 +21668,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -22055,7 +21694,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22079,7 +21718,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -22105,7 +21744,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22129,7 +21768,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -22155,7 +21794,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22179,7 +21818,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -22205,7 +21844,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22229,7 +21868,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -22255,7 +21894,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22279,7 +21918,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -22305,7 +21944,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22329,7 +21968,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -22355,7 +21994,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22379,7 +22018,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -22406,7 +22045,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22430,7 +22069,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -22457,7 +22096,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22481,7 +22120,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -22508,7 +22147,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22532,7 +22171,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -22559,7 +22198,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22583,7 +22222,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -22609,7 +22248,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22633,7 +22272,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -22659,7 +22298,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22683,7 +22322,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -22709,7 +22348,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22733,7 +22372,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -22759,7 +22398,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22783,7 +22422,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -22809,7 +22448,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22833,7 +22472,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -22859,7 +22498,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22883,7 +22522,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -22909,7 +22548,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22933,7 +22572,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -22959,7 +22598,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22983,7 +22622,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -23009,7 +22648,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23033,7 +22672,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -23059,7 +22698,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23083,7 +22722,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -23109,7 +22748,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23133,7 +22772,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -23159,7 +22798,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23183,7 +22822,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -23209,7 +22848,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23233,7 +22872,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -23259,7 +22898,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23283,7 +22922,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -23309,7 +22948,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23333,7 +22972,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -23359,7 +22998,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23383,7 +23022,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -23409,7 +23048,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23433,7 +23072,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -23459,7 +23098,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23483,7 +23122,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -23509,7 +23148,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23533,7 +23172,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -23559,7 +23198,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23583,7 +23222,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -23609,7 +23248,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23633,7 +23272,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -23659,7 +23298,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23683,7 +23322,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -23709,7 +23348,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23733,7 +23372,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -23759,7 +23398,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23783,7 +23422,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -23809,7 +23448,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23833,7 +23472,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -23859,7 +23498,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23883,7 +23522,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -23909,7 +23548,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23933,7 +23572,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -23959,7 +23598,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23983,7 +23622,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -24009,7 +23648,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24033,7 +23672,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -24059,7 +23698,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24083,7 +23722,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -24109,7 +23748,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24133,7 +23772,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -24159,7 +23798,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24183,7 +23822,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -24209,7 +23848,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24233,7 +23872,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -24259,7 +23898,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24283,7 +23922,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -24309,7 +23948,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24333,7 +23972,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -24359,7 +23998,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -24380,7 +24019,7 @@ "args": [ "--no-wpt-internal", "--xcode-build-version", - "15a5209g" + "15a5219j" ], "experiment_percentage": 100, "isolate_name": "chrome_ios_wpt", @@ -24412,7 +24051,7 @@ "hard_timeout": 14400, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" } ], @@ -42244,25 +41883,6 @@ "test_id_prefix": "ninja://chrome/test:browser_tests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter;../../testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_regressed_browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Ubuntu-22.04" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -42299,25 +41919,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter;../../testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_regressed_interactive_ui_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Ubuntu-22.04" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.linux.cr23_views_unittests.filter", "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" ], @@ -43085,9 +42686,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43096,8 +42697,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -43232,9 +42833,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43243,8 +42844,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -43364,9 +42965,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43375,8 +42976,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -44610,9 +44211,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44621,8 +44222,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -44757,9 +44358,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44768,8 +44369,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -44889,9 +44490,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44900,8 +44501,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -45532,9 +45133,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45543,8 +45144,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -48092,7 +47693,6 @@ "mac-cr23-rel": { "gtest_tests": [ { - "ci_only": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -48128,27 +47728,6 @@ "test_id_prefix": "ninja://chrome/test:browser_tests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter;../../testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" - ], - "ci_only": true, - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_regressed_browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-12" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -48185,26 +47764,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter;../../testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_regressed_interactive_ui_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-12" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.mac.cr23_views_unittests.filter", "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" ], @@ -50232,26 +49791,6 @@ "test_id_prefix": "ninja://chrome/test:browser_tests/" }, { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_regressed_browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -50288,25 +49827,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter;../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter", - "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "cr23_regressed_interactive_ui_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Windows-10" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "interactive_ui_tests", - "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" - }, - { - "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/cr23.win.cr23_views_unittests.filter", "--enable-features=ChromeRefresh2023,ChromeRefreshSecondary2023,ChromeWebuiRefresh2023,Cr2023ActionChips,Cr2023ActionChipsIcons,kOmniboxCR23SteadyStateIcons,OmniboxExpandedLayout,OmniboxExpandedStateColors,OmniboxExpandedStateHeight,OmniboxExpandedStateShape,OmniboxExpandedStateSuggestIcons,OmniboxSteadyStateBackgroundColor,OmniboxSteadyStateHeight,OmniboxSteadyStateTextColor,OmniboxSuggestionHoverFillShape" ],
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 343d6bf..f45116ae 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -4714,25 +4714,6 @@ "test_id_prefix": "ninja://chrome/test:telemetry_unittests/" }, { - "isolate_name": "test_env_py_unittests", - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "test_env_py_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-12" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://testing:test_env_py_unittests/" - }, - { "args": [ "--gtest-benchmark-name=views_perftests" ], @@ -4753,25 +4734,6 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ui/views:views_perftests/" - }, - { - "isolate_name": "xvfb_py_unittests", - "isolate_profile_data": true, - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "xvfb_py_unittests", - "resultdb": { - "enable": true - }, - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-12" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://testing:xvfb_py_unittests/" } ] }, @@ -6334,6 +6296,25 @@ "test_id_prefix": "ninja://chrome/test:telemetry_unittests/" }, { + "isolate_name": "test_env_py_unittests", + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "test_env_py_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "dimensions": { + "cpu": "x86-64", + "os": "Mac-13" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://testing:test_env_py_unittests/" + }, + { "args": [ "--gtest-benchmark-name=views_perftests" ], @@ -6354,6 +6335,25 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://ui/views:views_perftests/" + }, + { + "isolate_name": "xvfb_py_unittests", + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "xvfb_py_unittests", + "resultdb": { + "enable": true + }, + "swarming": { + "dimensions": { + "cpu": "x86-64", + "os": "Mac-13" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://testing:xvfb_py_unittests/" } ] }, @@ -7832,7 +7832,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -7859,7 +7859,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7881,7 +7881,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -7908,7 +7908,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7930,7 +7930,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -7957,7 +7957,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -7979,7 +7979,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -8006,7 +8006,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8028,7 +8028,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -8055,7 +8055,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8077,7 +8077,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -8104,7 +8104,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8126,7 +8126,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -8153,7 +8153,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8175,7 +8175,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -8202,7 +8202,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8224,7 +8224,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -8251,7 +8251,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8273,7 +8273,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -8300,7 +8300,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8322,7 +8322,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8349,7 +8349,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8371,7 +8371,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8398,7 +8398,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8420,7 +8420,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8447,7 +8447,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8469,7 +8469,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -8496,7 +8496,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8518,7 +8518,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -8545,7 +8545,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8567,7 +8567,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -8594,7 +8594,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8616,7 +8616,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -8643,7 +8643,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8665,7 +8665,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -8692,7 +8692,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8714,7 +8714,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8741,7 +8741,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8763,7 +8763,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8790,7 +8790,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8812,7 +8812,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8839,7 +8839,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8861,7 +8861,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -8888,7 +8888,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8910,7 +8910,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -8937,7 +8937,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -8959,7 +8959,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -8986,7 +8986,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9008,7 +9008,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -9038,7 +9038,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9061,7 +9061,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -9091,7 +9091,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9114,7 +9114,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -9141,7 +9141,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9163,7 +9163,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -9190,7 +9190,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9212,7 +9212,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -9239,7 +9239,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9261,7 +9261,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -9288,7 +9288,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9310,7 +9310,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -9337,7 +9337,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9359,7 +9359,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -9386,7 +9386,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9408,7 +9408,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -9435,7 +9435,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9458,7 +9458,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -9485,7 +9485,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9508,7 +9508,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -9535,7 +9535,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9557,7 +9557,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -9584,7 +9584,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9606,7 +9606,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -9633,7 +9633,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9655,7 +9655,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -9682,7 +9682,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9704,7 +9704,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -9731,7 +9731,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9753,7 +9753,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -9780,7 +9780,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9802,7 +9802,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -9829,7 +9829,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9851,7 +9851,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -9878,7 +9878,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9900,7 +9900,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -9928,7 +9928,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -9950,7 +9950,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -9978,7 +9978,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10000,7 +10000,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -10027,7 +10027,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10049,7 +10049,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -10076,7 +10076,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10098,7 +10098,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -10125,7 +10125,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10147,7 +10147,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -10174,7 +10174,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10196,7 +10196,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -10223,7 +10223,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10245,7 +10245,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -10272,7 +10272,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10294,7 +10294,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -10321,7 +10321,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10343,7 +10343,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -10370,7 +10370,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10392,7 +10392,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -10419,7 +10419,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10441,7 +10441,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -10468,7 +10468,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10490,7 +10490,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -10517,7 +10517,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10539,7 +10539,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -10566,7 +10566,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10588,7 +10588,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -10615,7 +10615,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10637,7 +10637,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -10664,7 +10664,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10686,7 +10686,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -10713,7 +10713,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10735,7 +10735,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -10762,7 +10762,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10784,7 +10784,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -10811,7 +10811,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10833,7 +10833,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -10860,7 +10860,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10882,7 +10882,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -10909,7 +10909,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10931,7 +10931,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -10958,7 +10958,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -10980,7 +10980,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -11007,7 +11007,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11029,7 +11029,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -11056,7 +11056,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11078,7 +11078,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -11105,7 +11105,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11127,7 +11127,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -11154,7 +11154,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11176,7 +11176,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -11203,7 +11203,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11225,7 +11225,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -11252,7 +11252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11274,7 +11274,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -11301,7 +11301,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11323,7 +11323,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -11350,7 +11350,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11379,7 +11379,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -11406,7 +11406,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11428,7 +11428,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -11455,7 +11455,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11477,7 +11477,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -11504,7 +11504,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11526,7 +11526,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -11553,7 +11553,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11575,7 +11575,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -11602,7 +11602,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11624,7 +11624,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -11651,7 +11651,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11673,7 +11673,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -11700,7 +11700,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11722,7 +11722,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -11749,7 +11749,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11771,7 +11771,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -11798,7 +11798,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11820,7 +11820,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -11847,7 +11847,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11869,7 +11869,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -11896,7 +11896,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11918,7 +11918,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -11945,7 +11945,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -11967,7 +11967,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -11994,7 +11994,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12016,7 +12016,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -12043,7 +12043,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12065,7 +12065,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -12092,7 +12092,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12114,7 +12114,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -12141,7 +12141,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12163,7 +12163,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -12190,7 +12190,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12212,7 +12212,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -12239,7 +12239,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12261,7 +12261,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -12288,7 +12288,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12310,7 +12310,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -12337,7 +12337,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12359,7 +12359,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -12386,7 +12386,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12408,7 +12408,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -12435,7 +12435,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12457,7 +12457,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -12484,7 +12484,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12506,7 +12506,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -12533,7 +12533,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12555,7 +12555,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12583,7 +12583,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12605,7 +12605,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12633,7 +12633,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12655,7 +12655,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12683,7 +12683,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12705,7 +12705,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -12733,7 +12733,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12755,7 +12755,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12785,7 +12785,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12808,7 +12808,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12838,7 +12838,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12861,7 +12861,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12891,7 +12891,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12914,7 +12914,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12944,7 +12944,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -12967,7 +12967,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -12997,7 +12997,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13020,7 +13020,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13050,7 +13050,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13073,7 +13073,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13103,7 +13103,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13126,7 +13126,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13156,7 +13156,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13179,7 +13179,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13209,7 +13209,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13232,7 +13232,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13262,7 +13262,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13285,7 +13285,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13313,7 +13313,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13336,7 +13336,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13364,7 +13364,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13387,7 +13387,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13415,7 +13415,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13438,7 +13438,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13466,7 +13466,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13489,7 +13489,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13517,7 +13517,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13539,7 +13539,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13567,7 +13567,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13589,7 +13589,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13617,7 +13617,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13639,7 +13639,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -13667,7 +13667,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13689,7 +13689,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13719,7 +13719,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13742,7 +13742,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13772,7 +13772,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13795,7 +13795,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13825,7 +13825,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13848,7 +13848,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--shards", "2", @@ -13878,7 +13878,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13901,7 +13901,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -13928,7 +13928,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13950,7 +13950,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -13977,7 +13977,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13999,7 +13999,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14026,7 +14026,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14048,7 +14048,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -14075,7 +14075,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14097,7 +14097,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14125,7 +14125,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14148,7 +14148,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14176,7 +14176,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14199,7 +14199,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14227,7 +14227,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14250,7 +14250,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14278,7 +14278,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14301,7 +14301,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -14328,7 +14328,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14350,7 +14350,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -14377,7 +14377,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14399,7 +14399,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -14426,7 +14426,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14449,7 +14449,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -14476,7 +14476,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14499,7 +14499,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -14526,7 +14526,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14548,7 +14548,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -14575,7 +14575,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14597,7 +14597,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14625,7 +14625,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14647,7 +14647,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14675,7 +14675,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14697,7 +14697,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14725,7 +14725,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14747,7 +14747,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -14775,7 +14775,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14797,7 +14797,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -14824,7 +14824,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14846,7 +14846,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -14873,7 +14873,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14895,7 +14895,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -14922,7 +14922,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14944,7 +14944,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -14971,7 +14971,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14993,7 +14993,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -15020,7 +15020,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15042,7 +15042,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -15069,7 +15069,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15091,7 +15091,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15119,7 +15119,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15141,7 +15141,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15169,7 +15169,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15191,7 +15191,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15219,7 +15219,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15241,7 +15241,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15269,7 +15269,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15291,7 +15291,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15319,7 +15319,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15341,7 +15341,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -15369,7 +15369,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15391,7 +15391,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -15418,7 +15418,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15440,7 +15440,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -15467,7 +15467,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15489,7 +15489,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -15516,7 +15516,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15538,7 +15538,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -15565,7 +15565,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15587,7 +15587,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -15614,7 +15614,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15636,7 +15636,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -15663,7 +15663,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15685,7 +15685,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -15712,7 +15712,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15734,7 +15734,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -15761,7 +15761,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15783,7 +15783,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -15810,7 +15810,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15832,7 +15832,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -15859,7 +15859,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15881,7 +15881,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -15908,7 +15908,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15930,7 +15930,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -15957,7 +15957,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15979,7 +15979,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -16006,7 +16006,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16028,7 +16028,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -16055,7 +16055,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16077,7 +16077,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -16104,7 +16104,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16126,7 +16126,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -16153,7 +16153,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16175,7 +16175,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -16202,7 +16202,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16224,7 +16224,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -16251,7 +16251,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16273,7 +16273,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -16300,7 +16300,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16322,7 +16322,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -16349,7 +16349,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16371,7 +16371,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -16398,7 +16398,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16420,7 +16420,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -16447,7 +16447,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16469,7 +16469,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -16496,7 +16496,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16518,7 +16518,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -16545,7 +16545,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16567,7 +16567,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -16594,7 +16594,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16616,7 +16616,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -16643,7 +16643,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16665,7 +16665,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -16692,7 +16692,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16714,7 +16714,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -16741,7 +16741,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16770,7 +16770,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -16796,7 +16796,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16818,7 +16818,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -16844,7 +16844,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16866,7 +16866,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -16892,7 +16892,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16914,7 +16914,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -16940,7 +16940,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16962,7 +16962,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -16988,7 +16988,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17010,7 +17010,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17036,7 +17036,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17058,7 +17058,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17084,7 +17084,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17106,7 +17106,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17132,7 +17132,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17154,7 +17154,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17180,7 +17180,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17202,7 +17202,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -17228,7 +17228,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17250,7 +17250,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17276,7 +17276,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17298,7 +17298,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17324,7 +17324,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17346,7 +17346,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17372,7 +17372,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17394,7 +17394,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17420,7 +17420,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17442,7 +17442,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17468,7 +17468,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17490,7 +17490,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17516,7 +17516,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17538,7 +17538,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17564,7 +17564,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17586,7 +17586,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17612,7 +17612,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17634,7 +17634,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17660,7 +17660,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17682,7 +17682,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -17708,7 +17708,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17730,7 +17730,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -17756,7 +17756,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17778,7 +17778,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -17804,7 +17804,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17826,7 +17826,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -17852,7 +17852,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17874,7 +17874,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -17900,7 +17900,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17922,7 +17922,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -17948,7 +17948,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -17970,7 +17970,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -17996,7 +17996,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18018,7 +18018,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -18044,7 +18044,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18066,7 +18066,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -18092,7 +18092,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18114,7 +18114,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -18140,7 +18140,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18162,7 +18162,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -18188,7 +18188,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18210,7 +18210,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18239,7 +18239,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18261,7 +18261,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18290,7 +18290,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18312,7 +18312,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18341,7 +18341,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18363,7 +18363,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18392,7 +18392,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18415,7 +18415,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18444,7 +18444,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18467,7 +18467,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18496,7 +18496,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18519,7 +18519,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18548,7 +18548,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18571,7 +18571,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18600,7 +18600,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18623,7 +18623,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18652,7 +18652,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18675,7 +18675,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18704,7 +18704,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18727,7 +18727,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18756,7 +18756,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18779,7 +18779,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18808,7 +18808,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18831,7 +18831,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18860,7 +18860,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18882,7 +18882,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18911,7 +18911,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18933,7 +18933,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -18962,7 +18962,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -18984,7 +18984,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19013,7 +19013,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19036,7 +19036,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19065,7 +19065,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19088,7 +19088,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19117,7 +19117,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19140,7 +19140,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19166,7 +19166,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19188,7 +19188,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19214,7 +19214,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19236,7 +19236,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19262,7 +19262,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19284,7 +19284,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19310,7 +19310,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19332,7 +19332,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19358,7 +19358,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19380,7 +19380,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19406,7 +19406,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19428,7 +19428,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19454,7 +19454,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19476,7 +19476,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19502,7 +19502,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19524,7 +19524,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19550,7 +19550,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19572,7 +19572,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -19598,7 +19598,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19620,7 +19620,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19649,7 +19649,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19672,7 +19672,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19701,7 +19701,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19724,7 +19724,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19753,7 +19753,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19776,7 +19776,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19803,7 +19803,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19825,7 +19825,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19852,7 +19852,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19874,7 +19874,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization" ], @@ -19901,7 +19901,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19923,7 +19923,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -19952,7 +19952,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -19974,7 +19974,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -20003,7 +20003,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20025,7 +20025,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -20054,7 +20054,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20076,7 +20076,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20102,7 +20102,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20124,7 +20124,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20150,7 +20150,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20172,7 +20172,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20198,7 +20198,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20220,7 +20220,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20246,7 +20246,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20268,7 +20268,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20294,7 +20294,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20316,7 +20316,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20342,7 +20342,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20364,7 +20364,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20390,7 +20390,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20412,7 +20412,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20438,7 +20438,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20460,7 +20460,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20486,7 +20486,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20508,7 +20508,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -20534,7 +20534,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20556,7 +20556,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -20585,7 +20585,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20607,7 +20607,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -20636,7 +20636,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20658,7 +20658,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest", "--xcode-parallelization", "--record-video", @@ -20687,7 +20687,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20709,7 +20709,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -20735,7 +20735,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20757,7 +20757,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -20783,7 +20783,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20805,7 +20805,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -20831,7 +20831,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20853,7 +20853,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -20879,7 +20879,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20901,7 +20901,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -20927,7 +20927,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20949,7 +20949,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -20975,7 +20975,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -20997,7 +20997,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -21023,7 +21023,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21045,7 +21045,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -21071,7 +21071,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21093,7 +21093,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -21119,7 +21119,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21141,7 +21141,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -21167,7 +21167,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21189,7 +21189,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21215,7 +21215,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21237,7 +21237,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21263,7 +21263,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21285,7 +21285,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21311,7 +21311,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21333,7 +21333,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21359,7 +21359,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21381,7 +21381,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21407,7 +21407,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21429,7 +21429,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21455,7 +21455,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21477,7 +21477,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21503,7 +21503,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21525,7 +21525,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21551,7 +21551,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21573,7 +21573,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21599,7 +21599,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21621,7 +21621,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -21647,7 +21647,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21669,7 +21669,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21695,7 +21695,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21717,7 +21717,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21743,7 +21743,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21765,7 +21765,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21791,7 +21791,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21813,7 +21813,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21839,7 +21839,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21861,7 +21861,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21887,7 +21887,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21909,7 +21909,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21935,7 +21935,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -21957,7 +21957,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -21983,7 +21983,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22005,7 +22005,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -22031,7 +22031,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22053,7 +22053,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -22079,7 +22079,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22101,7 +22101,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -22127,7 +22127,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22149,7 +22149,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22175,7 +22175,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22197,7 +22197,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22223,7 +22223,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22245,7 +22245,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22271,7 +22271,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22293,7 +22293,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22319,7 +22319,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22341,7 +22341,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22367,7 +22367,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22389,7 +22389,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22415,7 +22415,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22437,7 +22437,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22463,7 +22463,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22485,7 +22485,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22511,7 +22511,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22533,7 +22533,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22559,7 +22559,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22581,7 +22581,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -22607,7 +22607,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22629,7 +22629,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22655,7 +22655,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22677,7 +22677,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22703,7 +22703,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22725,7 +22725,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22751,7 +22751,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22773,7 +22773,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22799,7 +22799,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22821,7 +22821,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22847,7 +22847,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22869,7 +22869,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22895,7 +22895,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22917,7 +22917,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22943,7 +22943,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -22965,7 +22965,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -22991,7 +22991,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23013,7 +23013,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -23039,7 +23039,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -23061,7 +23061,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -23087,7 +23087,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 36fa614..69a2379 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -12976,7 +12976,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -13002,7 +13002,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13024,7 +13024,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "absl_hardening_tests", @@ -13050,7 +13050,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13072,7 +13072,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -13098,7 +13098,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13120,7 +13120,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "base_unittests", @@ -13146,7 +13146,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13168,7 +13168,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -13194,7 +13194,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13216,7 +13216,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_crypto_tests", @@ -13242,7 +13242,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13264,7 +13264,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -13290,7 +13290,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13312,7 +13312,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "boringssl_ssl_tests", @@ -13338,7 +13338,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13360,7 +13360,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -13386,7 +13386,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13408,7 +13408,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "components_unittests", @@ -13434,7 +13434,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13456,7 +13456,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -13482,7 +13482,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13504,7 +13504,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crashpad_tests", @@ -13530,7 +13530,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13552,7 +13552,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -13578,7 +13578,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13600,7 +13600,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "crypto_unittests", @@ -13626,7 +13626,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13648,7 +13648,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -13674,7 +13674,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13696,7 +13696,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "gfx_unittests", @@ -13722,7 +13722,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13744,7 +13744,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -13770,7 +13770,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13792,7 +13792,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "google_apis_unittests", @@ -13818,7 +13818,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13840,7 +13840,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -13866,7 +13866,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13888,7 +13888,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_chrome_unittests", @@ -13914,7 +13914,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13936,7 +13936,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -13962,7 +13962,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -13984,7 +13984,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_components_unittests", @@ -14010,7 +14010,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14032,7 +14032,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -14058,7 +14058,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14081,7 +14081,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_net_unittests", @@ -14107,7 +14107,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14130,7 +14130,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -14156,7 +14156,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14178,7 +14178,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -14204,7 +14204,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14226,7 +14226,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -14252,7 +14252,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14274,7 +14274,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_testing_unittests", @@ -14300,7 +14300,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14322,7 +14322,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -14348,7 +14348,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14370,7 +14370,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_inttests", @@ -14396,7 +14396,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14418,7 +14418,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -14444,7 +14444,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14466,7 +14466,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_unittests", @@ -14492,7 +14492,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14514,7 +14514,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -14540,7 +14540,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14562,7 +14562,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_inttests", @@ -14588,7 +14588,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14610,7 +14610,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -14636,7 +14636,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14658,7 +14658,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_web_view_unittests", @@ -14684,7 +14684,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14706,7 +14706,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -14732,7 +14732,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14754,7 +14754,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "net_unittests", @@ -14780,7 +14780,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14802,7 +14802,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -14828,7 +14828,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14850,7 +14850,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "services_unittests", @@ -14876,7 +14876,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14898,7 +14898,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -14924,7 +14924,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14946,7 +14946,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "skia_unittests", @@ -14972,7 +14972,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -14994,7 +14994,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -15020,7 +15020,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15042,7 +15042,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "sql_unittests", @@ -15068,7 +15068,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15090,7 +15090,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -15116,7 +15116,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15138,7 +15138,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ui_base_unittests", @@ -15164,7 +15164,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15186,7 +15186,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -15212,7 +15212,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -15234,7 +15234,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "url_unittests", @@ -15260,7 +15260,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -16123,12 +16123,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16138,8 +16138,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -16290,12 +16290,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16305,8 +16305,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": { @@ -16437,12 +16437,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 118.0.5963.0", + "description": "Run with ash-chrome version 118.0.5964.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16452,8 +16452,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v118.0.5963.0", - "revision": "version:118.0.5963.0" + "location": "lacros_version_skew_tests_v118.0.5964.0", + "revision": "version:118.0.5964.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json index 3b056369..00136f9 100644 --- a/testing/buildbot/chromium.webrtc.fyi.json +++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -627,7 +627,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -653,7 +653,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -675,7 +675,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -701,7 +701,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -723,7 +723,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -749,7 +749,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, { @@ -771,7 +771,7 @@ "--out-dir", "${ISOLATED_OUTDIR}", "--xcode-build-version", - "15a5209g", + "15a5219j", "--xctest" ], "isolate_name": "ios_remoting_unittests", @@ -797,7 +797,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a5209g", + "name": "xcode_ios_15a5219j", "path": "Xcode.app" }, {
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 664710c..5ad9341 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -57,7 +57,6 @@ "//testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter", "//testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter", "//testing/buildbot/filters/code_coverage.browser_tests.filter", - "//testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter", "//testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter", "//testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter", "//testing/buildbot/filters/cr23.win.cr23_browser_tests.filter", @@ -304,7 +303,6 @@ testonly = true data = [ - "//testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter", "//testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter", "//testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter", "//testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter",
diff --git a/testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter b/testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter deleted file mode 100644 index d007de8..0000000 --- a/testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter +++ /dev/null
@@ -1,17 +0,0 @@ -# browser_tests that are run with the Chrome2023Refresh feature flag enabled -# as the cr23_browser_tests test suite: -AccessibilityFocusHighlightBrowserTest.* -All/PromotionalTabsEnabledPolicyWhatsNewInvalidTest.* -BrowserNonClientFrameViewBrowserTest.* -CompanionPageBrowserTest.ReloadWillRefreshCompanion -ExtensionInstallDialogViewInteractiveBrowserTest.* -FullscreenTabSearchBubbleDialogTest.InvokeUi_default -IntentChipButtonBrowserTest.ShowsAppIconInChip -InteractiveBrowserTestBrowsertest.* -LoadImageBrowserTest.* -LocationIconViewBrowserTest.* -ManagedUiTest/ManagedUiTest.* -OutOfMemoryReporterPrerenderBrowserTest.* -PermissionRequestChipGestureSensitiveBrowserTest.* -PrivacySandboxDialogSmallWindowTest.* -WebAppBrowserTest.*
diff --git a/testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter b/testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter deleted file mode 100644 index 1e038bc..0000000 --- a/testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter +++ /dev/null
@@ -1,24 +0,0 @@ -# interactive_ui_tests that are run on the bots with the Chrome2023Refresh -# feature flag enabled as the cr23_regressed_interactive_ui_tests test suite: -AppMenuFullscreenInteractiveTest.* -AppMenuModelInteractiveTest.* -ExtensionsMenuModelInteractiveTest.* -ExtensionsMenuModelPresenceTest.* -FindInPageTest.* -FocusRingBrowserTest.* -FullscreenTabSearchBubbleDialogTest.InvokeUi_default -LocalCardMigrationBrowserTest.* -MdTextButtonTest.* -PasswordManagerMenuItemInteractiveTest.* -PermissionIndicatorsInteractiveUITest.* -PermissionsFlowInteractiveUITest.* -PriceTrackingBubbleInteractiveTest.* -PriceTrackingIconViewErrorHandelingTest.* -PriceTrackingIconViewInteractiveTest.* -TabDragging/DetachToBrowserTabDragControllerTest.* -TabHoverCardInteractiveUiTest.* -TestMenuControllerUITest.* -TouchableMenuItemViewTest.* - -# This may be a flaky failure unrelated to the c23 code paths. -SitePerProcessInteractivePDFTest.ContextMenuPositionForEmbeddedPDFInCrossOriginFrame
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 61b5e79..99ad693 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -1234,12 +1234,12 @@ 'xcode_15_main': { 'args': [ '--xcode-build-version', - '15a5209g', + '15a5219j', ], 'swarming': { 'named_caches': [ { - 'name': 'xcode_ios_15a5209g', + 'name': 'xcode_ios_15a5219j', 'path': 'Xcode.app', }, ],
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index fed95d7..9c7aebb 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1686,42 +1686,18 @@ }, # The `cr23` variants of tests run the normal test suites with - # `--enable-features=ChromeRefesh2023`. We do not have the capacity - # to run all of browser_tests and interactive_ui_tests in the CQ, - # so these suites define two variants of the two test suites. - # One set, in the `cr23_regressed_*tests` suites, are subsets of the whole - # test suites that previously failed. We hope will get us enough coverage of - # the feature to catch issues pre-submit. The others, in the `cr23_*tests` form, - # run the whole test suites, but they only run them on the `*cr23*` optional - # try bots and fyi bots. When tests start to fail in the `cr23_*tests` suites - # (and aren't also failing in the non-cr23 variety), we can add them - # to the `cr23_regressed_*tests` suites. + # `--enable-features=ChromeRefesh2023` and other refresh-related flags. + # The `fyi` versions of these test suites just include the normal + # versions of browser_tests and interactive_ui_tests to make it easier + # to garden the FYI bots and tell if a failure is likely to be + # cr23-specific or not. + 'cr23_fyi_linux_gtests': { 'browser_tests': { 'swarming': { 'shards': 20, }, }, - 'cr23_regressed_browser_tests': { - 'args': [ - ('--test-launcher-filter-file=' - '../../testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter;' - '../../testing/buildbot/filters/cr23.linux.cr23_browser_tests.filter' - ), - ], - 'test': 'browser_tests', - 'mixins': [ 'chrome-refresh-2023' ], - }, - 'cr23_regressed_interactive_ui_tests': { - 'args': [ - ('--test-launcher-filter-file=' - '../../testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter;' - '../../testing/buildbot/filters/cr23.linux.cr23_interactive_ui_tests.filter' - ), - ], - 'test': 'interactive_ui_tests', - 'mixins': [ 'chrome-refresh-2023' ], - }, 'interactive_ui_tests': { 'swarming': { 'shards': 10, @@ -1733,34 +1709,6 @@ 'swarming': { 'shards': 20, }, - 'ci_only': True, - }, - 'cr23_regressed_browser_tests': { - 'args': [ - ('--test-launcher-filter-file=' - '../../testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter;' - '../../testing/buildbot/filters/cr23.mac.cr23_browser_tests.filter' - ), - ], - 'swarming': { - 'shards': 20, - }, - 'test': 'browser_tests', - 'ci_only': True, - 'mixins': [ 'chrome-refresh-2023' ], - }, - 'cr23_regressed_interactive_ui_tests': { - 'args': [ - ('--test-launcher-filter-file=' - '../../testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter;' - '../../testing/buildbot/filters/cr23.mac.cr23_interactive_ui_tests.filter' - ), - ], - 'swarming': { - 'shards': 10, - }, - 'test': 'interactive_ui_tests', - 'mixins': [ 'chrome-refresh-2023' ], }, 'interactive_ui_tests': { 'swarming': { @@ -1774,29 +1722,6 @@ 'shards': 20, }, }, - 'cr23_regressed_browser_tests': { - 'args': [ - ('--test-launcher-filter-file=' - '../../testing/buildbot/filters/cr23.tests.cr23_browser_tests.filter;' - '../../testing/buildbot/filters/cr23.win.cr23_browser_tests.filter' - ), - ], - 'swarming': { - 'shards': 20, - }, - 'test': 'browser_tests', - 'mixins': [ 'chrome-refresh-2023' ], - }, - 'cr23_regressed_interactive_ui_tests': { - 'args': [ - ('--test-launcher-filter-file=' - '../../testing/buildbot/filters/cr23.tests.cr23_interactive_ui_tests.filter;' - '../../testing/buildbot/filters/cr23.win.cr23_interactive_ui_tests.filter' - ), - ], - 'test': 'interactive_ui_tests', - 'mixins': [ 'chrome-refresh-2023' ], - }, 'interactive_ui_tests': { 'swarming': { 'shards': 10, @@ -5962,6 +5887,24 @@ }, }, + 'wpt_web_tests_android': { + 'wpt_tests_suite': { + 'merge': { + 'args': [ + '--verbose', + '--test-list', + '//third_party/blink/web_tests/TestLists/Default.txt' + ], + 'script': '//third_party/blink/tools/merge_web_test_results.py', + }, + 'isolate_name': 'chrome_public_wpt', + 'results_handler': 'layout tests', + 'swarming': { + 'shards': 15, + }, + }, + }, + 'wpt_web_tests_content_shell': { 'wpt_tests_suite': { 'merge': { @@ -7563,7 +7506,6 @@ 'variants': [ 'SIM_IPHONE_14_17_0', 'SIM_IPAD_AIR_5TH_GEN_17_0', - 'SIM_IPHONE_14_PRO_MAX_17_0', ] }, 'ios_eg2_cq_tests': {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 7ceb1d1..980fdbb 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -16,16 +16,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 118.0.5963.0', + 'description': 'Run with ash-chrome version 118.0.5964.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5963.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5964.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v118.0.5963.0', - 'revision': 'version:118.0.5963.0', + 'location': 'lacros_version_skew_tests_v118.0.5964.0', + 'revision': 'version:118.0.5964.0', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 8c26b409..0ac4a80 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1207,6 +1207,19 @@ }, 'os_type': 'android', }, + 'android-chrome-pie-x86-wpt-android-specific': { + 'mixins': [ + 'has_native_resultdb_integration', + 'pie-x86-emulator', + 'emulator-8-cores', + 'linux-jammy', + 'x86-64', + ], + 'test_suites': { + 'isolated_scripts': 'wpt_web_tests_android', + }, + 'os_type': 'android', + }, 'android-chrome-pie-x86-wpt-fyi-rel': { 'mixins': [ 'has_native_resultdb_integration', @@ -5065,7 +5078,7 @@ ], 'test_suites': { 'gtest_tests': 'chromium_mac_gtests_no_nacl', - 'isolated_scripts': 'chromium_mac_rel_isolated_scripts_once', + 'isolated_scripts': 'chromium_mac_rel_isolated_scripts', }, }, 'Mac13 Tests': { @@ -5075,7 +5088,7 @@ ], 'test_suites': { 'gtest_tests': 'chromium_mac_gtests_no_nacl_no_nocompile', - 'isolated_scripts': 'chromium_mac_rel_isolated_scripts', + 'isolated_scripts': 'chromium_mac_rel_isolated_scripts_once', }, }, 'Mac13 Tests (dbg)': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 17e3900..79ff961 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5771,6 +5771,21 @@ ] } ], + "EnableImmediateDrawDuringScrollInteraction": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "DrawImmediatelyWhenInteractive", + "enable_features": [ + "DrawImmediatelyWhenInteractive" + ] + } + ] + } + ], "EnableMSAAOnNewIntelGPUs": [ { "platforms": [ @@ -16936,6 +16951,25 @@ ] } ], + "WebProtectPrintAfterDialog": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableCloudScanAfterPreview" + ] + } + ] + } + ], "WebProtectUrlFiltering": [ { "platforms": [
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node.cc b/third_party/blink/renderer/core/css/css_math_expression_node.cc index d3d16eb..6a7d677 100644 --- a/third_party/blink/renderer/core/css/css_math_expression_node.cc +++ b/third_party/blink/renderer/core/css/css_math_expression_node.cc
@@ -1975,7 +1975,7 @@ CSSMathExpressionNode* ParseMathFunction( CSSValueID function_id, CSSParserTokenRange& tokens, - HashMap<CSSValueID, double> color_channel_keyword_values, + const HashMap<CSSValueID, double> color_channel_keyword_values, int depth) { if (!IsSupportedMathFunction(function_id)) { return nullptr; @@ -2168,7 +2168,7 @@ private: CSSMathExpressionNode* ParseValue( CSSParserTokenRange& tokens, - HashMap<CSSValueID, double> color_channel_keyword_values) { + const HashMap<CSSValueID, double> color_channel_keyword_values) { CSSParserToken token = tokens.ConsumeIncludingWhitespace(); if (token.Id() == CSSValueID::kInfinity) { return CSSMathExpressionNumericLiteral::Create( @@ -2242,7 +2242,7 @@ CSSMathExpressionNode* ParseValueTerm( CSSParserTokenRange& tokens, - HashMap<CSSValueID, double> color_channel_keyword_values, + const HashMap<CSSValueID, double> color_channel_keyword_values, int depth) { if (tokens.AtEnd()) { return nullptr; @@ -2276,7 +2276,7 @@ CSSMathExpressionNode* ParseValueMultiplicativeExpression( CSSParserTokenRange& tokens, - HashMap<CSSValueID, double> color_channel_keyword_values, + const HashMap<CSSValueID, double> color_channel_keyword_values, int depth) { if (tokens.AtEnd()) { return nullptr; @@ -2315,7 +2315,7 @@ CSSMathExpressionNode* ParseAdditiveValueExpression( CSSParserTokenRange& tokens, - HashMap<CSSValueID, double> color_channel_keyword_values, + const HashMap<CSSValueID, double> color_channel_keyword_values, int depth) { if (tokens.AtEnd()) { return nullptr; @@ -2361,7 +2361,7 @@ CSSMathExpressionNode* ParseValueExpression( CSSParserTokenRange& tokens, - HashMap<CSSValueID, double> color_channel_keyword_values, + const HashMap<CSSValueID, double> color_channel_keyword_values, int depth) { if (++depth > kMaxExpressionDepth) { return nullptr; @@ -2629,7 +2629,7 @@ const CSSParserContext& context, const bool is_percentage_allowed, CSSAnchorQueryTypes allowed_anchor_queries, - HashMap<CSSValueID, double> color_channel_keyword_values) { + const HashMap<CSSValueID, double> color_channel_keyword_values) { CSSMathExpressionNodeParser parser(context, is_percentage_allowed, allowed_anchor_queries); CSSMathExpressionNode* result = parser.ParseMathFunction(
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node.h b/third_party/blink/renderer/core/css/css_math_expression_node.h index 7997adf3..6efbccca 100644 --- a/third_party/blink/renderer/core/css/css_math_expression_node.h +++ b/third_party/blink/renderer/core/css/css_math_expression_node.h
@@ -84,7 +84,7 @@ CSSAnchorQueryTypes allowed_anchor_queries, // Variable substitutions for relative color syntax. // https://www.w3.org/TR/css-color-5/#relative-colors - HashMap<CSSValueID, double> color_channel_keyword_values = {}); + const HashMap<CSSValueID, double> color_channel_keyword_values = {}); virtual bool IsNumericLiteral() const { return false; } virtual bool IsOperation() const { return false; }
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5 index ec1cf79..bfc3ae8 100644 --- a/third_party/blink/renderer/core/css/css_value_keywords.json5 +++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1285,7 +1285,7 @@ "type", // deprecated gradients - "from", + // "from", now part of relative color syntax "to", "color-stop", "radial", @@ -1370,6 +1370,25 @@ // The color-mix function https://www.w3.org/TR/css-color-5/#color-mix "color-mix", + // relative color syntax + "from", + // RCS channel keywords. + // r, g, b for rgb(), rgba() and color() + // x, y, z are already defined for "scale" + // h, s, l for hsl() + // h, w, b for hwb() + // l, a, b for lab() and oklab() + // l, c, h for lch() and oklch() + "r", + "g", + "b", + "h", + "s", + "l", + "w", + "a", + "c", + // transform "matrix", "matrix3d",
diff --git a/third_party/blink/renderer/core/css/properties/css_color_function_parser.cc b/third_party/blink/renderer/core/css/properties/css_color_function_parser.cc index 251d8e0..bf7395d 100644 --- a/third_party/blink/renderer/core/css/properties/css_color_function_parser.cc +++ b/third_party/blink/renderer/core/css/properties/css_color_function_parser.cc
@@ -3,6 +3,9 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/css/properties/css_color_function_parser.h" +#include "third_party/blink/renderer/core/css/css_color.h" +#include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" #include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h" #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" #include "third_party/blink/renderer/core/css_value_keywords.h" @@ -65,9 +68,124 @@ return false; } -bool ColorFunctionParser::ConsumeColorSpace(CSSParserTokenRange& range, - const CSSParserContext& context, - CSSParserTokenRange& args) { +// https://www.w3.org/TR/css-color-5/#relative-colors +// e.g. lab(from magenta l a b), consume the "magenta" after the from. The +// result needs to be a blink::Color as we need actual values for the color +// parameters. +static bool ConsumeRelativeOriginColor(CSSParserTokenRange& args, + const CSSParserContext& context, + Color& result) { + if (!RuntimeEnabledFeatures::CSSRelativeColorEnabled()) { + return false; + } + // TODO(crbug.com/1447327): Just like with css_parsing_utils::ResolveColor(), + // currentcolor is not currently handled well. + if (CSSValue* css_color = css_parsing_utils::ConsumeColor(args, context)) { + if (auto* color_value = DynamicTo<cssvalue::CSSColor>(css_color)) { + result = color_value->Value(); + return true; + } else { + CSSValueID value_id = To<CSSIdentifierValue>(css_color)->GetValueID(); + // TODO(crbug.com/1447327): Handle color scheme. + result = StyleColor::ColorFromKeyword(value_id, + mojom::blink::ColorScheme::kLight); + return true; + } + } + return false; +} + +static absl::optional<double> ConsumeRelativeColorChannel( + CSSParserTokenRange& input_range, + const CSSParserContext& context, + const HashMap<CSSValueID, double> color_channel_keyword_values) { + const CSSParserToken& token = input_range.Peek(); + // Relative color channels can be calc() functions with color channel + // replacements. e.g. In "color(from magenta srgb calc(r / 2) 0 0)", the + // "calc" should substitute "1" for "r" (magenta has a full red channel). + if (token.GetType() == kFunctionToken) { + // Don't consume the range if the parsing fails. + CSSParserTokenRange calc_range = input_range; + CSSMathFunctionValue* calc_value = CSSMathFunctionValue::Create( + CSSMathExpressionNode::ParseMathFunction( + token.FunctionId(), css_parsing_utils::ConsumeFunction(calc_range), + context, true /* is_percentage_allowed */, kCSSAnchorQueryTypesNone, + color_channel_keyword_values), + CSSPrimitiveValue::ValueRange::kAll); + if (calc_value) { + if (calc_value->Category() != kCalcNumber) { + return absl::nullopt; + } + // Consume the range, since it has succeeded. + input_range = calc_range; + return calc_value->GetDoubleValueWithoutClamping(); + } + } + + // This is for just single variable swaps without calc(). e.g. The "l" in + // "lab(from cyan l 0.5 0.5)". + if (color_channel_keyword_values.Contains(token.Id())) { + input_range.ConsumeIncludingWhitespace(); + return color_channel_keyword_values.at(token.Id()); + } + + return absl::nullopt; +} + +// Relative color syntax requires "channel keyword" substitutions for color +// channels. Each color space has three "channel keywords", plus "alpha", that +// correspond to the three parameters stored on the origin color. This function +// generates a map between the channel keywords and the stored values in order +// to make said substitutions. e.g. color(from magenta srgb r g b) will need to +// generate srgb keyword values for the origin color "magenta". This function +// will return: {CSSValueID::kR: 1, CSSValueID::kG: 0, CSSValueID::kB: 1}. +static HashMap<CSSValueID, double> GenerateChannelKeywordValues( + Color::ColorSpace color_space, + Color origin_color) { + std::vector<CSSValueID> channel_names; + switch (color_space) { + case Color::ColorSpace::kSRGB: + case Color::ColorSpace::kSRGBLinear: + case Color::ColorSpace::kSRGBLegacy: + case Color::ColorSpace::kDisplayP3: + case Color::ColorSpace::kA98RGB: + case Color::ColorSpace::kProPhotoRGB: + case Color::ColorSpace::kRec2020: + case Color::ColorSpace::kXYZD50: + case Color::ColorSpace::kXYZD65: + channel_names = {CSSValueID::kR, CSSValueID::kG, CSSValueID::kB}; + break; + case Color::ColorSpace::kLab: + case Color::ColorSpace::kOklab: + channel_names = {CSSValueID::kL, CSSValueID::kA, CSSValueID::kB}; + break; + case Color::ColorSpace::kLch: + case Color::ColorSpace::kOklch: + channel_names = {CSSValueID::kL, CSSValueID::kC, CSSValueID::kH}; + break; + case Color::ColorSpace::kHSL: + channel_names = {CSSValueID::kH, CSSValueID::kS, CSSValueID::kL}; + break; + case Color::ColorSpace::kHWB: + channel_names = {CSSValueID::kH, CSSValueID::kW, CSSValueID::kB}; + break; + case Color::ColorSpace::kNone: + NOTREACHED(); + break; + } + + return { + {channel_names[0], origin_color.Param0()}, + {channel_names[1], origin_color.Param1()}, + {channel_names[2], origin_color.Param2()}, + {CSSValueID::kAlpha, origin_color.Alpha()}, + }; +} + +bool ColorFunctionParser::ConsumeColorSpaceAndOriginColor( + CSSParserTokenRange& range, + const CSSParserContext& context, + CSSParserTokenRange& args) { // Get the color space. This will either be the name of the function, or it // will be the first argument of the "color" function. CSSValueID function_id = range.Peek().FunctionId(); @@ -80,6 +198,12 @@ // This is in the form color(COLOR_SPACE r g b) if (function_id == CSSValueID::kColor) { + if (css_parsing_utils::ConsumeIdent<CSSValueID::kFrom>(args)) { + if (!ConsumeRelativeOriginColor(args, context, origin_color_)) { + return false; + } + is_relative_color_ = true; + } color_space_ = CSSValueIDToColorSpace(args.ConsumeIncludingWhitespace().Id()); if (!Color::IsPredefinedColorSpace(color_space_)) { @@ -87,6 +211,33 @@ } } + if (css_parsing_utils::ConsumeIdent<CSSValueID::kFrom>(args)) { + // Can't have more than one "from" in a single color. + // Relative color is invalid for rgba()/hsla functions + if (is_relative_color_ || function_id == CSSValueID::kRgba || + function_id == CSSValueID::kHsla || + !ConsumeRelativeOriginColor(args, context, origin_color_)) { + return false; + } + is_relative_color_ = true; + } + + if (is_relative_color_) { + origin_color_.ConvertToColorSpace(color_space_); + channel_keyword_values_ = + GenerateChannelKeywordValues(color_space_, origin_color_); + if (Color::IsPredefinedColorSpace(color_space_)) { + // Relative colors with color() can use 'x', 'y', 'z' in the place of 'r', + // 'g', 'b'. + xyz_keyword_values_ = { + {CSSValueID::kX, origin_color_.Param0()}, + {CSSValueID::kY, origin_color_.Param1()}, + {CSSValueID::kZ, origin_color_.Param2()}, + {CSSValueID::kAlpha, origin_color_.Alpha()}, + }; + } + } + return true; } @@ -100,6 +251,9 @@ return false; } if (css_parsing_utils::ConsumeCommaIncludingWhitespace(args)) { + if (is_relative_color_) { + return false; + } is_legacy_syntax_ = true; } if (css_parsing_utils::ConsumeIdent<CSSValueID::kNone>(args)) { @@ -114,6 +268,11 @@ channels_[i] = temp->GetDoubleValue(); channel_types_[i] = ChannelType::kNumber; return true; + } else if (is_relative_color_ && + (channels_[i] = ConsumeRelativeColorChannel( + args, context, channel_keyword_values_))) { + channel_types_[i] = ChannelType::kRelative; + return true; } else { return false; } @@ -133,6 +292,28 @@ return true; } + if (is_relative_color_) { + channel_types_[i] = ChannelType::kRelative; + // First, check if the channel contains only the keyword "alpha", because + // that can be either an rgb or an xyz param. + if ((channels_[i] = ConsumeRelativeColorChannel( + args, context, {{CSSValueID::kAlpha, origin_color_.Alpha()}}))) { + return true; + } + if ((channels_[i] = ConsumeRelativeColorChannel(args, context, + channel_keyword_values_))) { + uses_rgb_relative_params_ = true; + return true; + } + + if (Color::IsPredefinedColorSpace(color_space_) && + (channels_[i] = + ConsumeRelativeColorChannel(args, context, xyz_keyword_values_))) { + uses_xyz_relative_params_ = true; + return true; + } + } + // Missing components should not parse. return false; } @@ -161,6 +342,26 @@ return true; } + if ((alpha_ = ConsumeRelativeColorChannel( + args, context, {{CSSValueID::kAlpha, origin_color_.Alpha()}}))) { + // Same as above, check if the channel contains only the keyword + // "alpha", because that can be either an rgb or an xyz param. + return true; + } + + if (is_relative_color_ && (alpha_ = ConsumeRelativeColorChannel( + args, context, channel_keyword_values_))) { + uses_rgb_relative_params_ = true; + return true; + } + + if (is_relative_color_ && Color::IsPredefinedColorSpace(color_space_) && + (alpha_ = + ConsumeRelativeColorChannel(args, context, xyz_keyword_values_))) { + uses_xyz_relative_params_ = true; + return true; + } + return false; } @@ -173,12 +374,12 @@ bool uses_bare_numbers = false; for (int i = 0; i < 3; i++) { if (channel_types_[i] == ChannelType::kPercentage) { - if (uses_bare_numbers) { + if (uses_bare_numbers && !is_relative_color_) { return false; } uses_percentage = true; } else if (channel_types_[i] == ChannelType::kNumber) { - if (uses_percentage) { + if (uses_percentage && !is_relative_color_) { return false; } uses_bare_numbers = true; @@ -266,16 +467,18 @@ CSSParserTokenRange range = input_range; CSSParserTokenRange args = range; - if (!ConsumeColorSpace(range, context, args)) { + if (!ConsumeColorSpaceAndOriginColor(range, context, args)) { return false; } + // Parse the three color channel params. for (int i = 0; i < 3; i++) { if (!ConsumeChannel(args, context, i)) { return false; } } + // Parse alpha. bool expect_alpha = false; if (css_parsing_utils::ConsumeSlashIncludingWhitespace(args)) { expect_alpha = true; @@ -289,9 +492,15 @@ if (expect_alpha && !ConsumeAlpha(args, context)) { return false; } + if (!expect_alpha && is_relative_color_) { + alpha_ = channel_keyword_values_.at(CSSValueID::kAlpha); + } + // Cannot mix the two color channel keyword types. // "None" is not a part of the legacy syntax. - if (!args.AtEnd() || (is_legacy_syntax_ && has_none_)) { + if (!args.AtEnd() || + (uses_rgb_relative_params_ && uses_xyz_relative_params_) || + (is_legacy_syntax_ && has_none_)) { return false; } @@ -299,6 +508,9 @@ return false; } + // TODO(crbug.com/1447327) We should return color(srgb ... ) colors for legacy + // color spaces, but a lot of test expectations need to change for that. See: + // https://github.com/w3c/csswg-drafts/issues/8444 result = Color::FromColorSpace(color_space_, channels_[0], channels_[1], channels_[2], alpha_); // The parsing was successful, so we need to consume the input.
diff --git a/third_party/blink/renderer/core/css/properties/css_color_function_parser.h b/third_party/blink/renderer/core/css/properties/css_color_function_parser.h index e760b5913..826d5c6dc 100644 --- a/third_party/blink/renderer/core/css/properties/css_color_function_parser.h +++ b/third_party/blink/renderer/core/css/properties/css_color_function_parser.h
@@ -22,10 +22,10 @@ Color& result); private: - enum class ChannelType { kNone, kPercentage, kNumber }; - bool ConsumeColorSpace(CSSParserTokenRange& range, - const CSSParserContext& context, - CSSParserTokenRange& args); + enum class ChannelType { kNone, kPercentage, kNumber, kRelative }; + bool ConsumeColorSpaceAndOriginColor(CSSParserTokenRange& range, + const CSSParserContext& context, + CSSParserTokenRange& args); bool ConsumeChannel(CSSParserTokenRange& args, const CSSParserContext& context, int index); @@ -41,6 +41,14 @@ // incompatible with CSSColor4 features like "none" or alpha with a slash. bool is_legacy_syntax_ = false; bool has_none_ = false; + + // For relative colors + bool is_relative_color_ = false; + Color origin_color_; + HashMap<CSSValueID, double> channel_keyword_values_; + HashMap<CSSValueID, double> xyz_keyword_values_; + bool uses_rgb_relative_params_ = false; + bool uses_xyz_relative_params_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index da294637..62c2ef2b 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -5152,8 +5152,7 @@ void Element::focusForBindings(const FocusOptions* options) { Focus(FocusParams(SelectionBehaviorOnFocus::kRestore, mojom::blink::FocusType::kScript, - /*capabilities=*/nullptr, options, - /*gate_on_user_activation=*/true)); + /*capabilities=*/nullptr, options)); } void Element::Focus() { @@ -5191,7 +5190,7 @@ FocusOptions* focus_options = nullptr; bool should_consume_user_activation = false; - if (params.gate_on_user_activation) { + if (params.focus_trigger == FocusTrigger::kScript) { LocalFrame& frame = *GetDocument().GetFrame(); if (!frame.AllowFocusWithoutUserActivation() && !LocalFrame::HasTransientUserActivation(&frame)) { @@ -5213,8 +5212,7 @@ FocusParams params_to_use = FocusParams( params.selection_behavior, params.type, params.source_capabilities, - focus_options ? focus_options : params.options, - params.gate_on_user_activation); + focus_options ? focus_options : params.options, params.focus_trigger); // Ensure we have clean style (including forced display locks). GetDocument().UpdateStyleAndLayoutTreeForNode(this,
diff --git a/third_party/blink/renderer/core/dom/focus_params.h b/third_party/blink/renderer/core/dom/focus_params.h index bbfd64785..60121ff 100644 --- a/third_party/blink/renderer/core/dom/focus_params.h +++ b/third_party/blink/renderer/core/dom/focus_params.h
@@ -12,24 +12,34 @@ namespace blink { +// Focus changes that cross a fenced frame boundary are observable by both +// frames involved in the focus change. Because of that, focus calls that +// originate from a JavaScript call can be used as a communication channel +// between a fenced frame and its embedder. For those focus calls, we gate focus +// on user activation to ensure that a user has recently interacted with a frame +// before allowing focus to happen. By default, we assume focus can be used as a +// communication channel. However, if a focus call can only be triggered +// directly through user interaction and can't be triggered via script, it is +// safe to not gate the focus call on user activation. +enum class FocusTrigger { kScript, kUserGesture }; + struct FocusParams { STACK_ALLOCATED(); public: FocusParams() : options(FocusOptions::Create()) {} - explicit FocusParams(bool gate_on_user_activation) - : options(FocusOptions::Create()), - gate_on_user_activation(gate_on_user_activation) {} + explicit FocusParams(FocusTrigger focus_trigger) + : options(FocusOptions::Create()), focus_trigger(focus_trigger) {} FocusParams(SelectionBehaviorOnFocus selection, mojom::blink::FocusType focus_type, InputDeviceCapabilities* capabilities, const FocusOptions* focus_options = FocusOptions::Create(), - bool gate_on_user_activation = false) + FocusTrigger focus_trigger = FocusTrigger::kScript) : selection_behavior(selection), type(focus_type), source_capabilities(capabilities), options(focus_options), - gate_on_user_activation(gate_on_user_activation) {} + focus_trigger(focus_trigger) {} SelectionBehaviorOnFocus selection_behavior = SelectionBehaviorOnFocus::kRestore; @@ -37,7 +47,7 @@ InputDeviceCapabilities* source_capabilities = nullptr; const FocusOptions* options = nullptr; bool omit_blur_events = false; - bool gate_on_user_activation = false; + FocusTrigger focus_trigger = FocusTrigger::kScript; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index ee8e0335..2ad84b6 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -94,6 +94,7 @@ #include "third_party/blink/renderer/core/dom/document_type.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h" #include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/editor.h" @@ -3327,7 +3328,7 @@ return; next_element->scrollIntoViewIfNeeded(true /*centerIfNeeded*/); - next_element->Focus(); + next_element->Focus(FocusParams(FocusTrigger::kUserGesture)); } void LocalFrame::PostMessageEvent(
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index 21d04b2f..4c6ff1f 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h" #include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" @@ -727,7 +728,7 @@ return; next_element->scrollIntoViewIfNeeded(true /*centerIfNeeded*/); - next_element->Focus(); + next_element->Focus(FocusParams(FocusTrigger::kUserGesture)); } void LocalFrameMojoHandler::ReportContentSecurityPolicyViolation(
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 492f56d..9a42e18 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
@@ -65,6 +65,7 @@ #include "third_party/blink/renderer/core/content_capture/content_capture_manager.h" #include "third_party/blink/renderer/core/core_initializer.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" #include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/ephemeral_range.h" @@ -605,10 +606,10 @@ } if (auto* text_control = EnclosingTextControl(stylus_writable_element)) { - text_control->Focus(); + text_control->Focus(FocusParams(FocusTrigger::kUserGesture)); } else if (auto* html_element = DynamicTo<HTMLElement>(stylus_writable_element)) { - html_element->Focus(); + html_element->Focus(FocusParams(FocusTrigger::kUserGesture)); } Element* focused_element = FocusedElement(); // Since the element can change after it gets focused, we just verify if @@ -3986,10 +3987,12 @@ } void WebFrameWidgetImpl::CopyToFindPboard() { +#if BUILDFLAG(IS_MAC) WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); if (!focused_frame) return; To<WebLocalFrameImpl>(focused_frame)->CopyToFindPboard(); +#endif } void WebFrameWidgetImpl::CenterSelection() {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 1681afe8..95ac953 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -871,8 +871,10 @@ } void WebLocalFrameImpl::CopyToFindPboard() { +#if BUILDFLAG(IS_MAC) if (HasSelection()) GetFrame()->GetSystemClipboard()->CopyToFindPboard(SelectionAsText()); +#endif } void WebLocalFrameImpl::CenterSelection() {
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc index 4e30192..3526a38 100644 --- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc +++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
@@ -28,6 +28,7 @@ #include "base/ranges/algorithm.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/events/mouse_event.h" #include "third_party/blink/renderer/core/frame/use_counter_impl.h" @@ -656,7 +657,7 @@ GetDocument().UpdateStyleAndLayoutTreeForNode(old_focused_field, DocumentUpdateReason::kFocus); if (index != kInvalidFieldIndex && old_focused_field->IsFocusable()) { - old_focused_field->Focus(); + old_focused_field->Focus(FocusParams(FocusTrigger::kUserGesture)); return; } } @@ -687,7 +688,7 @@ for (wtf_size_t field_index = start_index; field_index < fields_.size(); ++field_index) { if (fields_[field_index]->IsFocusable()) { - fields_[field_index]->Focus(); + fields_[field_index]->Focus(FocusParams(FocusTrigger::kUserGesture)); return true; } } @@ -711,7 +712,7 @@ while (field_index > 0) { --field_index; if (fields_[field_index]->IsFocusable()) { - fields_[field_index]->Focus(); + fields_[field_index]->Focus(FocusParams(FocusTrigger::kUserGesture)); return true; } } @@ -794,7 +795,7 @@ } if (DateTimeFieldElement* field = FieldAt(std::min(focused_field_index, fields_.size() - 1))) - field->Focus(); + field->Focus(FocusParams(FocusTrigger::kUserGesture)); } if (last_child_to_be_removed) {
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.cc b/third_party/blink/renderer/core/html/forms/html_button_element.cc index 91b73fd..69d2627 100644 --- a/third_party/blink/renderer/core/html/forms/html_button_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_button_element.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" @@ -159,7 +160,7 @@ void HTMLButtonElement::AccessKeyAction( SimulatedClickCreationScope creation_scope) { - Focus(); + Focus(FocusParams(FocusTrigger::kUserGesture)); DispatchSimulatedClick(nullptr, creation_scope); }
diff --git a/third_party/blink/renderer/core/html/forms/html_label_element.cc b/third_party/blink/renderer/core/html/forms/html_label_element.cc index 925f2710..0eacde44 100644 --- a/third_party/blink/renderer/core/html/forms/html_label_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_label_element.cc
@@ -207,9 +207,9 @@ // In case of double click or triple click, selection will be there, // so do not focus the control element. if (!is_label_text_selected) { - element->Focus(FocusParams( - SelectionBehaviorOnFocus::kRestore, mojom::blink::FocusType::kMouse, - nullptr, FocusOptions::Create(), /*gate_on_user_activation=*/true)); + element->Focus(FocusParams(SelectionBehaviorOnFocus::kRestore, + mojom::blink::FocusType::kMouse, nullptr, + FocusOptions::Create())); } } @@ -249,7 +249,8 @@ // To match other browsers, always restore previous selection. if (HTMLElement* element = control()) { element->Focus(FocusParams(SelectionBehaviorOnFocus::kRestore, params.type, - params.source_capabilities, params.options)); + params.source_capabilities, params.options, + params.focus_trigger)); } }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 9a90ec3..59971bf 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" #include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" @@ -428,7 +429,7 @@ void HTMLSelectElement::AccessKeyAction( SimulatedClickCreationScope creation_scope) { - Focus(); + Focus(FocusParams(FocusTrigger::kUserGesture)); DispatchSimulatedClick(nullptr, creation_scope); }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_list_element.cc b/third_party/blink/renderer/core/html/forms/html_select_list_element.cc index 65a812e..f6bae89 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_list_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_list_element.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h" #include "third_party/blink/renderer/core/dom/text.h" @@ -533,7 +534,7 @@ PseudoStateChanged(CSSSelector::kPseudoClosed); PseudoStateChanged(CSSSelector::kPseudoOpen); if (selectedOption()) { - selectedOption()->Focus(); + selectedOption()->Focus(FocusParams(FocusTrigger::kUserGesture)); } selected_option_when_listbox_opened_ = selectedOption(); } @@ -566,7 +567,7 @@ SetSelectedOption(OptionAtListIndex(index), /*send_events=*/true); if (open() && selectedOption()) { - selectedOption()->Focus(); + selectedOption()->Focus(FocusParams(FocusTrigger::kUserGesture)); } selected_option_->SetDirty(true); @@ -577,7 +578,7 @@ PseudoStateChanged(CSSSelector::kPseudoClosed); PseudoStateChanged(CSSSelector::kPseudoOpen); if (button_part_) { - button_part_->Focus(); + button_part_->Focus(FocusParams(FocusTrigger::kUserGesture)); } if (selectedOption() != selected_option_when_listbox_opened_) { DispatchChangeEvent(); @@ -1076,7 +1077,7 @@ if (element->IsDisabledFormControl()) continue; SetSelectedOption(element); - element->Focus(); + element->Focus(FocusParams(FocusTrigger::kUserGesture)); DispatchInputAndChangeEventsIfNeeded(); return; } @@ -1091,7 +1092,7 @@ if (element->IsDisabledFormControl()) continue; SetSelectedOption(element); - element->Focus(); + element->Focus(FocusParams(FocusTrigger::kUserGesture)); DispatchInputAndChangeEventsIfNeeded(); return; }
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc index 7f346f4..d47ef3e 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" @@ -661,7 +662,7 @@ } void HTMLTextAreaElement::AccessKeyAction(SimulatedClickCreationScope) { - Focus(); + Focus(FocusParams(FocusTrigger::kUserGesture)); } void HTMLTextAreaElement::setCols(unsigned cols) {
diff --git a/third_party/blink/renderer/core/html/forms/input_type_view.cc b/third_party/blink/renderer/core/html/forms/input_type_view.cc index 54527bf..44d0fe2 100644 --- a/third_party/blink/renderer/core/html/forms/input_type_view.cc +++ b/third_party/blink/renderer/core/html/forms/input_type_view.cc
@@ -79,8 +79,9 @@ } void InputTypeView::AccessKeyAction(SimulatedClickCreationScope) { - GetElement().Focus(FocusParams(SelectionBehaviorOnFocus::kReset, - mojom::blink::FocusType::kNone, nullptr)); + GetElement().Focus(FocusParams( + SelectionBehaviorOnFocus::kReset, mojom::blink::FocusType::kNone, nullptr, + FocusOptions::Create(), FocusTrigger::kUserGesture)); } bool InputTypeView::ShouldSubmitImplicitly(const Event& event) {
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.cc b/third_party/blink/renderer/core/html/forms/listed_element.cc index 83bf19b..af7d256 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.cc +++ b/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -521,9 +521,9 @@ Element& element = ValidationAnchor(); element.scrollIntoViewIfNeeded(false); if (element.IsFocusable()) - element.Focus(FocusParams(/*gate_on_user_activation=*/true)); + element.Focus(); else - ToHTMLElement().Focus(FocusParams(/*gate_on_user_activation=*/true)); + ToHTMLElement().Focus(); UpdateVisibleValidationMessage(); }
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc index ecbfc9eb..769389c 100644 --- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc +++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -35,6 +35,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/events/mouse_event.h" @@ -438,7 +439,7 @@ // If a field element has focus, set focus back to the <input> itself before // deleting the field. This prevents unnecessary focusout/blur events. if (ContainsFocusedShadowElement()) - GetElement().Focus(); + GetElement().Focus(FocusParams(FocusTrigger::kUserGesture)); InputTypeView::DestroyShadowSubtree(); is_destroying_shadow_subtree_ = false; @@ -668,7 +669,7 @@ } void MultipleFieldsTemporalInputTypeView::FocusAndSelectClearButtonOwner() { - GetElement().Focus(); + GetElement().Focus(FocusParams(FocusTrigger::kUserGesture)); } bool MultipleFieldsTemporalInputTypeView::
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc index 21e969a..6b32e4b 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -236,7 +236,8 @@ ->FiresTouchEvents(mouse_event->FromTouch()); select_->Focus(FocusParams(SelectionBehaviorOnFocus::kRestore, mojom::blink::FocusType::kMouse, - source_capabilities)); + source_capabilities, FocusOptions::Create(), + FocusTrigger::kUserGesture)); if (select_->GetLayoutObject() && !will_be_destroyed_ && !select_->IsDisabledFormControl()) { if (PopupIsVisible()) { @@ -283,7 +284,7 @@ } bool MenuListSelectType::HandlePopupOpenKeyboardEvent() { - select_->Focus(); + select_->Focus(FocusParams(FocusTrigger::kUserGesture)); // Calling focus() may cause us to lose our LayoutObject. Return true so // that our caller doesn't process the event further, but don't set // the event as handled. @@ -718,7 +719,7 @@ const auto* mouse_event = DynamicTo<MouseEvent>(event); const auto* gesture_event = DynamicTo<GestureEvent>(event); if (event.type() == event_type_names::kGesturetap && gesture_event) { - select_->Focus(); + select_->Focus(FocusParams(FocusTrigger::kUserGesture)); // Calling focus() may cause us to lose our layoutObject or change the // layoutObject type, in which case do not want to handle the event. if (!select_->GetLayoutObject() || will_be_destroyed_) @@ -740,7 +741,7 @@ if (event.type() == event_type_names::kMousedown && mouse_event && mouse_event->button() == static_cast<int16_t>(WebPointerProperties::Button::kLeft)) { - select_->Focus(); + select_->Focus(FocusParams(FocusTrigger::kUserGesture)); // Calling focus() may cause us to lose our layoutObject, in which case // do not want to handle the event. if (!select_->GetLayoutObject() || will_be_destroyed_ ||
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc index e6188d62..44051b3 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -246,7 +246,7 @@ // the selection. Focus(FocusParams(SelectionBehaviorOnFocus::kNone, mojom::blink::FocusType::kScript, nullptr, - FocusOptions::Create(), /*gate_on_user_activation=*/true)); + FocusOptions::Create())); RestoreCachedSelection(); }
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc index 5842bb6..2f9da8fc 100644 --- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/html/forms/text_field_input_type.h" #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/events/before_text_inserted_event.h" @@ -631,7 +632,7 @@ } void TextFieldInputType::FocusAndSelectSpinButtonOwner() { - GetElement().Focus(); + GetElement().Focus(FocusParams(FocusTrigger::kUserGesture)); GetElement().SetSelectionRange(0, std::numeric_limits<int>::max()); }
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.cc b/third_party/blink/renderer/core/html/html_dialog_element.cc index c48e85a..1535f61 100644 --- a/third_party/blink/renderer/core/html/html_dialog_element.cc +++ b/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -81,7 +81,7 @@ // 3. Run the focusing steps for control. if (control->IsFocusable()) - control->Focus(FocusParams(/*gate_on_user_activation=*/true)); + control->Focus(); else document.ClearFocusedElement(); @@ -178,7 +178,7 @@ if (previously_focused_element && (was_modal || descendant_is_focused)) { previously_focused_element->Focus(FocusParams( SelectionBehaviorOnFocus::kNone, mojom::blink::FocusType::kScript, - nullptr, focus_options, /*gate_on_user_activation=*/true)); + nullptr, focus_options)); } }
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index ca5a638..9ea9f6d 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1861,8 +1861,7 @@ focus_options->setPreventScroll(true); previously_focused_element->Focus(FocusParams( SelectionBehaviorOnFocus::kRestore, mojom::blink::FocusType::kScript, - /*capabilities=*/nullptr, focus_options, - /*gate_on_user_activation=*/true)); + /*capabilities=*/nullptr, focus_options)); } } @@ -1904,7 +1903,7 @@ return; // 3. Run the focusing steps for control. - control->Focus(FocusParams(/*gate_on_user_activation=*/true)); + control->Focus(); // 4. Let topDocument be the active document of control's node document's // browsing context's top-level browsing context. @@ -2457,6 +2456,9 @@ EqualIgnoringASCIICase(direction, "auto"); } +// TODO(https://crbug.com/576815): Once the CSSPseudoDir flag is +// removed, this function no longer needs to be templatized over +// Traversal since it can always use NodeTraversal. template <typename Traversal> absl::optional<TextDirection> HTMLElement::ResolveAutoDirectionality( bool& is_deferred, @@ -2484,7 +2486,7 @@ } auto* slot = ToHTMLSlotElementIfSupportsAssignmentOrNull(node); - if (slot) { + if (slot && !RuntimeEnabledFeatures::CSSPseudoDirEnabled()) { ShadowRoot* root = slot->ContainingShadowRoot(); // Defer to adjust the directionality to avoid recalcuating slot // assignment in FlatTreeTraversal when updating slot. @@ -2506,6 +2508,18 @@ } } + // TODO(https://crbug.com/576815): Once we have final spec text for + // https://github.com/whatwg/html/issues/3699 we should recheck the + // relative order of this check and the "Skip elements with valid + // dir attribute" check above, and add tests for the case that + // exercises both. (Note that if the order is switched, this test + // needs to consider the dir attribute on the slot element rather + // than just jumping to its shadow host.) + if (slot && RuntimeEnabledFeatures::CSSPseudoDirEnabled()) { + ShadowRoot* root = slot->ContainingShadowRoot(); + return root->host().CachedDirectionality(); + } + if (node->IsTextNode()) { if (const absl::optional<TextDirection> text_direction = BidiParagraph::BaseDirectionForString(node->textContent(true))) {
diff --git a/third_party/blink/renderer/core/html/plugin_document.cc b/third_party/blink/renderer/core/html/plugin_document.cc index 89f9e639..3c4bffe 100644 --- a/third_party/blink/renderer/core/html/plugin_document.cc +++ b/third_party/blink/renderer/core/html/plugin_document.cc
@@ -150,7 +150,7 @@ frame->View()->FlushAnyPendingPostLayoutTasks(); // Focus the plugin here, as the line above is where the plugin is created. if (frame->IsMainFrame()) { - embed_element_->Focus(FocusParams(/*gate_on_user_activation=*/true)); + embed_element_->Focus(); if (IsStopped()) { // Possibly detached by a mutation event listener installed in // runScriptsAtDocumentElementAvailable.
diff --git a/third_party/blink/renderer/core/input/keyboard_event_manager.cc b/third_party/blink/renderer/core/input/keyboard_event_manager.cc index ee349aa..a13d921 100644 --- a/third_party/blink/renderer/core/input/keyboard_event_manager.cc +++ b/third_party/blink/renderer/core/input/keyboard_event_manager.cc
@@ -197,7 +197,8 @@ if (!elem) return false; elem->Focus(FocusParams(SelectionBehaviorOnFocus::kReset, - mojom::blink::FocusType::kAccessKey, nullptr)); + mojom::blink::FocusType::kAccessKey, nullptr, + FocusOptions::Create(), FocusTrigger::kUserGesture)); elem->AccessKeyAction(SimulatedClickCreationScope::kFromUserAgent); return true; }
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc index 37bb43f..0df748ca4 100644 --- a/third_party/blink/renderer/core/input/mouse_event_manager.cc +++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -584,9 +584,9 @@ if (Element* delegated_target = element.GetFocusableArea()) { // Use FocusType::kMouse instead of FocusType::kForward // in order to prevent :focus-visible from being set - delegated_target->Focus(FocusParams(SelectionBehaviorOnFocus::kReset, - mojom::blink::FocusType::kMouse, - nullptr)); + delegated_target->Focus(FocusParams( + SelectionBehaviorOnFocus::kReset, mojom::blink::FocusType::kMouse, + nullptr, FocusOptions::Create(), FocusTrigger::kUserGesture)); return true; } return false;
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc index 0a54860..acdcbd5 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -51,6 +51,7 @@ #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/pseudo_element.h" @@ -1448,7 +1449,7 @@ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInspector); if (!element->IsFocusable()) return protocol::Response::ServerError("Element is not focusable"); - element->Focus(); + element->Focus(FocusParams(FocusTrigger::kUserGesture)); return protocol::Response::Success(); }
diff --git a/third_party/blink/renderer/core/navigation_api/navigate_event.cc b/third_party/blink/renderer/core/navigation_api/navigate_event.cc index 5fcae5c..90ff627 100644 --- a/third_party/blink/renderer/core/navigation_api/navigate_event.cc +++ b/third_party/blink/renderer/core/navigation_api/navigate_event.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/event_interface_names.h" #include "third_party/blink/renderer/core/event_type_names.h" #include "third_party/blink/renderer/core/frame/deprecation/deprecation.h" @@ -400,7 +401,7 @@ } if (Element* focus_delegate = document->GetAutofocusDelegate()) { - focus_delegate->Focus(); + focus_delegate->Focus(FocusParams(FocusTrigger::kUserGesture)); } else { document->ClearFocusedElement(); document->SetSequentialFocusNavigationStartingPoint(nullptr);
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc index 0ae5298b..fab94e7 100644 --- a/third_party/blink/renderer/core/page/focus_controller.cc +++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1227,8 +1227,9 @@ SetFocusedFrame(new_document.GetFrame()); - element->Focus( - FocusParams(SelectionBehaviorOnFocus::kReset, type, source_capabilities)); + element->Focus(FocusParams(SelectionBehaviorOnFocus::kReset, type, + source_capabilities, FocusOptions::Create(), + FocusTrigger::kUserGesture)); return true; }
diff --git a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc index 8543857..05185d7 100644 --- a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc +++ b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
@@ -210,7 +210,7 @@ // clear focus, which matches the behavior of other browsers. auto* element = DynamicTo<Element>(anchor_node_.Get()); if (element && element->IsFocusable()) { - element->Focus(FocusParams(/*gate_on_user_activation=*/true)); + element->Focus(); } else { frame_->GetDocument()->SetSequentialFocusNavigationStartingPoint( anchor_node_);
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc index 2211c2a..eabb792 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -219,7 +219,8 @@ enter_key_down_seen_ && enter_key_press_seen_) { interest_element->Focus( FocusParams(SelectionBehaviorOnFocus::kReset, - mojom::blink::FocusType::kSpatialNavigation, nullptr)); + mojom::blink::FocusType::kSpatialNavigation, nullptr, + FocusOptions::Create(), FocusTrigger::kUserGesture)); // We need enter to activate links, etc. The click should be after the // focus in case the site transfers focus upon clicking. interest_element->DispatchSimulatedClick( @@ -500,7 +501,8 @@ element->Focus(FocusParams(SelectionBehaviorOnFocus::kReset, mojom::blink::FocusType::kSpatialNavigation, - nullptr)); + nullptr, FocusOptions::Create(), + FocusTrigger::kUserGesture)); // The focused element could be changed due to elm.focus() on focus handlers. // So we need to update the current focused element before DispatchMouseMove. // This is tested in snav-applies-hover-with-focused.html. @@ -599,7 +601,8 @@ if (IsA<HTMLMediaElement>(element)) { element->Focus(FocusParams(SelectionBehaviorOnFocus::kReset, mojom::blink::FocusType::kSpatialNavigation, - nullptr)); + nullptr, FocusOptions::Create(), + FocusTrigger::kUserGesture)); } }
diff --git a/third_party/blink/renderer/core/timing/largest_contentful_paint.cc b/third_party/blink/renderer/core/timing/largest_contentful_paint.cc index 263a1b50..4752328 100644 --- a/third_party/blink/renderer/core/timing/largest_contentful_paint.cc +++ b/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
@@ -13,10 +13,10 @@ LargestContentfulPaint::LargestContentfulPaint( double start_time, - base::TimeDelta render_time, + DOMHighResTimeStamp render_time, uint64_t size, - base::TimeDelta load_time, - base::TimeDelta first_animated_frame_time, + DOMHighResTimeStamp load_time, + DOMHighResTimeStamp first_animated_frame_time, const AtomicString& id, const String& url, Element* element, @@ -60,10 +60,9 @@ void LargestContentfulPaint::BuildJSONValue(V8ObjectBuilder& builder) const { PerformanceEntry::BuildJSONValue(builder); builder.Add("size", size_); - builder.Add("renderTime", render_time_.InMillisecondsF()); - builder.Add("loadTime", load_time_.InMillisecondsF()); - builder.Add("firstAnimatedFrameTime", - first_animated_frame_time_.InMillisecondsF()); + builder.Add("renderTime", render_time_); + builder.Add("loadTime", load_time_); + builder.Add("firstAnimatedFrameTime", first_animated_frame_time_); builder.Add("id", id_); builder.Add("url", url_); }
diff --git a/third_party/blink/renderer/core/timing/largest_contentful_paint.h b/third_party/blink/renderer/core/timing/largest_contentful_paint.h index 07004e2..3ed0867 100644 --- a/third_party/blink/renderer/core/timing/largest_contentful_paint.h +++ b/third_party/blink/renderer/core/timing/largest_contentful_paint.h
@@ -20,10 +20,10 @@ public: LargestContentfulPaint(double start_time, - base::TimeDelta render_time, + DOMHighResTimeStamp render_time, uint64_t size, - base::TimeDelta load_time, - base::TimeDelta first_animated_frame_time, + DOMHighResTimeStamp load_time, + DOMHighResTimeStamp first_animated_frame_time, const AtomicString& id, const String& url, Element* element, @@ -35,12 +35,10 @@ PerformanceEntryType EntryTypeEnum() const override; uint64_t size() const { return size_; } - DOMHighResTimeStamp renderTime() const { - return render_time_.InMillisecondsF(); - } - DOMHighResTimeStamp loadTime() const { return load_time_.InMillisecondsF(); } + DOMHighResTimeStamp renderTime() const { return render_time_; } + DOMHighResTimeStamp loadTime() const { return load_time_; } DOMHighResTimeStamp firstAnimatedFrameTime() const { - return first_animated_frame_time_.InMillisecondsF(); + return first_animated_frame_time_; } const AtomicString& id() const { return id_; } const String& url() const { return url_; } @@ -52,9 +50,9 @@ void BuildJSONValue(V8ObjectBuilder&) const override; uint64_t size_; - base::TimeDelta render_time_; - base::TimeDelta load_time_; - base::TimeDelta first_animated_frame_time_; + DOMHighResTimeStamp render_time_; + DOMHighResTimeStamp load_time_; + DOMHighResTimeStamp first_animated_frame_time_; AtomicString id_; String url_; WeakMember<Element> element_;
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc index 1e2322c..2c626c25 100644 --- a/third_party/blink/renderer/core/timing/window_performance.cc +++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -907,10 +907,12 @@ bool is_triggered_by_soft_navigation) { DOMHighResTimeStamp start_timestamp = MonotonicTimeToDOMHighResTimeStamp(start_time); - base::TimeDelta render_timestamp = MonotonicTimeToTimeDelta(render_time); - base::TimeDelta load_timestamp = MonotonicTimeToTimeDelta(load_time); - base::TimeDelta first_animated_frame_timestamp = - MonotonicTimeToTimeDelta(first_animated_frame_time); + DOMHighResTimeStamp render_timestamp = + MonotonicTimeToDOMHighResTimeStamp(render_time); + DOMHighResTimeStamp load_timestamp = + MonotonicTimeToDOMHighResTimeStamp(load_time); + DOMHighResTimeStamp first_animated_frame_timestamp = + MonotonicTimeToDOMHighResTimeStamp(first_animated_frame_time); // TODO(yoav): Should we modify start to represent the animated frame? auto* entry = MakeGarbageCollected<LargestContentfulPaint>( start_timestamp, render_timestamp, paint_size, load_timestamp,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 5a810e7..2c5fa077 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -50,6 +50,7 @@ #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h" #include "third_party/blink/renderer/core/dom/css_toggle_inference.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" @@ -5123,7 +5124,7 @@ } } - element->Focus(); + element->Focus(FocusParams(FocusTrigger::kUserGesture)); // Calling NotifyUserActivation here allows the browser to activate features // that need user activation, such as showing an autofill suggestion.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection.cc b/third_party/blink/renderer/modules/accessibility/ax_selection.cc index 29496ef..a04f02b 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_selection.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/accessibility/ax_selection.h" #include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/range.h" #include "third_party/blink/renderer/core/editing/ephemeral_range.h" @@ -369,7 +370,7 @@ // TextControl::SetSelectionRange deliberately does not set focus. But if // we're updating the selection, the text control should be focused. ScheduleSelectEvent(text_control); - text_control.Focus(); + text_control.Focus(FocusParams(FocusTrigger::kUserGesture)); return true; }
diff --git a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc index 4d686dd..9e47ea8 100644 --- a/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc +++ b/third_party/blink/renderer/modules/ad_auction/navigator_auction.cc
@@ -76,6 +76,7 @@ #include "third_party/blink/renderer/platform/wtf/text/string_operators.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "url/url_constants.h" #include "v8/include/v8-primitive.h" #include "v8/include/v8-value.h" @@ -2364,6 +2365,11 @@ } RecordCommonFledgeUseCounters(navigator.DomWindow()->document()); const ExecutionContext* context = ExecutionContext::From(script_state); + if (context->GetSecurityOrigin()->Protocol() != url::kHttpsScheme) { + exception_state.ThrowSecurityError( + "May only joinAdInterestGroup from an https origin."); + return ScriptPromise(); + } if (!context->IsFeatureEnabled( mojom::blink::PermissionsPolicyFeature::kJoinAdInterestGroup)) { exception_state.ThrowDOMException( @@ -2973,6 +2979,13 @@ return ScriptPromise(); } + if (ExecutionContext::From(script_state)->GetSecurityOrigin()->Protocol() != + url::kHttpsScheme) { + exception_state.ThrowSecurityError( + "May only leaveAdInterestGroup from an https origin."); + return ScriptPromise(); + } + bool is_cross_origin = !ExecutionContext::From(script_state) ->GetSecurityOrigin() ->IsSameOriginWith(owner.get()); @@ -3000,13 +3013,18 @@ ScriptState* script_state, ExceptionState& exception_state) { LocalDOMWindow* window = GetSupplementable()->DomWindow(); - if (!window) { exception_state.ThrowSecurityError( "May not leaveAdInterestGroup from a Document that is not fully " "active"); return ScriptPromise(); } + if (ExecutionContext::From(script_state)->GetSecurityOrigin()->Protocol() != + url::kHttpsScheme) { + exception_state.ThrowSecurityError( + "May only leaveAdInterestGroup from an https origin."); + return ScriptPromise(); + } if (!window->GetFrame()->IsInFencedFrameTree()) { exception_state.ThrowTypeError( "owner and name are required outside of a fenced frame.");
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc index 7342823..c47cb39 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_union_boolean_scrollintoviewoptions.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" @@ -251,7 +252,7 @@ auto* arg = MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options); checked_item_->scrollIntoView(arg); - checked_item_->Focus(); + checked_item_->Focus(FocusParams(FocusTrigger::kUserGesture)); } void MediaControlPlaybackSpeedListElement::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc index cfd68286..32e8535 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/event_type_names.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -151,7 +152,8 @@ void MediaControlPopupMenuElement::DefaultEventHandler(Event& event) { if (event.type() == event_type_names::kPointermove && event.target() != this) { - To<Element>(event.target()->ToNode())->Focus(); + To<Element>(event.target()->ToNode()) + ->Focus(FocusParams(FocusTrigger::kUserGesture)); last_focused_element_ = To<Element>(event.target()->ToNode()); } else if (event.type() == event_type_names::kFocusout) { GetDocument() @@ -175,7 +177,9 @@ if (last_focused_element_) { FocusOptions* focus_options = FocusOptions::Create(); focus_options->setPreventScroll(true); - last_focused_element_->Focus(focus_options); + last_focused_element_->Focus(FocusParams( + SelectionBehaviorOnFocus::kNone, mojom::blink::FocusType::kNone, + nullptr, focus_options, FocusTrigger::kUserGesture)); } } @@ -267,7 +271,7 @@ if (!element->InlineStyle() || !element->InlineStyle()->HasProperty(CSSPropertyID::kDisplay)) { - element->Focus(); + element->Focus(FocusParams(FocusTrigger::kUserGesture)); last_focused_element_ = element; return true; } @@ -308,14 +312,14 @@ void MediaControlPopupMenuElement::CloseFromKeyboard() { SetIsWanted(false); - PopupAnchor()->Focus(); + PopupAnchor()->Focus(FocusParams(FocusTrigger::kUserGesture)); } void MediaControlPopupMenuElement::FocusPopupAnchorIfOverflowClosed() { if (!GetMediaControls().OverflowMenuIsWanted() && !GetMediaControls().PlaybackSpeedListIsWanted() && !GetMediaControls().TextTrackListIsWanted()) { - PopupAnchor()->Focus(); + PopupAnchor()->Focus(FocusParams(FocusTrigger::kUserGesture)); } }
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc index 1bfc578..9affad6b 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -686,6 +686,8 @@ return WGPUFeatureName_IndirectFirstInstance; case V8GPUFeatureName::Enum::kChromiumExperimentalDp4A: return WGPUFeatureName_ChromiumExperimentalDp4a; + case V8GPUFeatureName::Enum::kChromiumExperimentalReadWriteStorageTexture: + return WGPUFeatureName_ChromiumExperimentalReadWriteStorageTexture; case V8GPUFeatureName::Enum::kRg11B10UfloatRenderable: return WGPUFeatureName_RG11B10UfloatRenderable; case V8GPUFeatureName::Enum::kBgra8UnormStorage:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index 6e11932..3eaa61d 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -53,6 +53,9 @@ return V8GPUFeatureName::Enum::kBgra8UnormStorage; case WGPUFeatureName_ChromiumExperimentalDp4a: return V8GPUFeatureName::Enum::kChromiumExperimentalDp4A; + case WGPUFeatureName_ChromiumExperimentalReadWriteStorageTexture: + return V8GPUFeatureName::Enum:: + kChromiumExperimentalReadWriteStorageTexture; case WGPUFeatureName_ShaderF16: return V8GPUFeatureName::Enum::kShaderF16; case WGPUFeatureName_Float32Filterable:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl index 97f526e..0da4b78 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
@@ -21,6 +21,7 @@ "pipeline-statistics-query", "timestamp-query-inside-passes", "chromium-experimental-dp4a", + "chromium-experimental-read-write-storage-texture", }; [
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc index deb3e66d..c9f1b18 100644 --- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
@@ -1005,22 +1005,22 @@ angle = container->irot.angle; CHECK_LT(angle, 4); } - // |mode| specifies how the mirroring is performed. + // |axis| specifies how the mirroring is performed. // -1: No mirroring. // 0: The top and bottom parts of the image are exchanged. // 1: The left and right parts of the image are exchanged. - int mode = -1; + int axis = -1; if (container->transformFlags & AVIF_TRANSFORM_IMIR) { - mode = container->imir.mode; - CHECK_LT(mode, 2); + axis = container->imir.axis; + CHECK_LT(axis, 2); } // MIAF Section 7.3.6.7 (Clean aperture, rotation and mirror) says: // These properties, if used, shall be indicated to be applied in the // following order: clean aperture first, then rotation, then mirror. // - // In the kModeAngleToOrientation array, the first dimension is mode (with an + // In the kAxisAngleToOrientation array, the first dimension is axis (with an // offset of 1). The second dimension is angle. - constexpr ImageOrientationEnum kModeAngleToOrientation[3][4] = { + constexpr ImageOrientationEnum kAxisAngleToOrientation[3][4] = { // No mirroring. {ImageOrientationEnum::kOriginTopLeft, ImageOrientationEnum::kOriginLeftBottom, @@ -1037,7 +1037,7 @@ ImageOrientationEnum::kOriginBottomLeft, ImageOrientationEnum::kOriginLeftTop}, }; - orientation_ = kModeAngleToOrientation[mode + 1][angle]; + orientation_ = kAxisAngleToOrientation[axis + 1][angle]; // Determine whether the image can be decoded to YUV. // * Alpha channel is not supported.
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index 4edcfac8..d752a7b 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -2614,10 +2614,10 @@ DCHECK(is_flinging_); DCHECK(main_task_runner_->BelongsToCurrentThread()); - if (state == media::MediaStatus::State::PLAYING && Paused()) { + if (state == media::MediaStatus::State::kPlaying && Paused()) { DVLOG(1) << __func__ << " requesting PLAY."; client_->ResumePlayback(); - } else if (state == media::MediaStatus::State::PAUSED && !Paused()) { + } else if (state == media::MediaStatus::State::kPaused && !Paused()) { DVLOG(1) << __func__ << " requesting PAUSE."; client_->PausePlayback( WebMediaPlayerClient::PauseReason::kRemotePlayStateChange);
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 7a0091a..5125853f 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1035,6 +1035,11 @@ base_feature: "none", }, { + // https://drafts.csswg.org/css-color-5/#relative-colors + name: "CSSRelativeColor", + status: "experimental", + }, + { // https://drafts.csswg.org/css-cascade-6/#scoped-styles name: "CSSScope", status: "stable", @@ -1990,7 +1995,7 @@ }, { name: "HTMLSearchElement", - status: "experimental", + status: "stable", }, { name: "HTMLSelectListElement",
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc index a1d70a17..39c7450 100644 --- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc +++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
@@ -103,6 +103,10 @@ } #if BUILDFLAG(IS_MAC) +BASE_FEATURE(kIncreaseTileMemorySizeProportionally, + "IncreaseTileMemorySizeProportionally", + base::FEATURE_ENABLED_BY_DEFAULT); + // Adjusting tile memory size in case a lot more websites need more tile // memory than the current calculation. BASE_FEATURE(kAdjustTileGpuMemorySize, @@ -230,37 +234,56 @@ DCHECK_EQ(actual.bytes_limit_when_visible, previous_value); #elif BUILDFLAG(IS_MAC) - // This calculation will increase the tile memory size. It should apply to - // the other plateforms if no regression on Mac. - actual.priority_cutoff_when_visible = - gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; + if (base::FeatureList::IsEnabled(kIncreaseTileMemorySizeProportionally)) { + // This calculation will increase the tile memory size. It should apply to + // the other plateforms if no regression on Mac. + actual.priority_cutoff_when_visible = + gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; - // For large monitors with high resolution, increase the tile memory to avoid - // frequent out of memory problems. With Mac M1 on https://www.334-28th.com/, - // it seems 512 MB works fine on 1920x1080 * 2 (scale) and 1152 MB on - // 2056x1329 * 2 (scale). Use this ratio for the formula to increase - // |bytes_limit_when_visible| proportionally. - constexpr size_t kLargeResolution = 2056 * 1329 * 2 * 2; - size_t display_size = - std::round(initial_screen_size.width() * initial_device_scale_factor * - initial_screen_size.height() * initial_device_scale_factor); + // For large monitors with high resolution, increase the tile memory to + // avoid frequent out of memory problems. With Mac M1 on + // https://www.334-28th.com/, it seems 512 MB works fine on 1920x1080 * 2 + // (scale) and 1152 MB on 2056x1329 * 2 (scale). Use this ratio for the + // formula to increase |bytes_limit_when_visible| proportionally. + constexpr size_t kLargeResolution = 2056 * 1329 * 2 * 2; + size_t display_size = + std::round(initial_screen_size.width() * initial_device_scale_factor * + initial_screen_size.height() * initial_device_scale_factor); - size_t large_resolution_memory_mb = GetLargeResolutionMemoryMB(); - size_t mb_limit_when_visible = - large_resolution_memory_mb * (display_size * 1.0 / kLargeResolution); + size_t large_resolution_memory_mb = GetLargeResolutionMemoryMB(); + size_t mb_limit_when_visible = + large_resolution_memory_mb * (display_size * 1.0 / kLargeResolution); - // Cap the memory size to one fourth of the total system memory so it won't - // consume too much of the system memory. Still keep the minimum to the - // default of 512MB. - size_t default_memory_mb = GetDefaultMemoryMB(); - size_t memory_cap_mb = base::SysInfo::AmountOfPhysicalMemoryMB() / 4; - if (mb_limit_when_visible > memory_cap_mb) { - mb_limit_when_visible = memory_cap_mb; - } else if (mb_limit_when_visible < default_memory_mb) { - mb_limit_when_visible = default_memory_mb; + // Cap the memory size to one fourth of the total system memory so it won't + // consume too much of the system memory. Still keep the minimum to the + // default of 512MB. + size_t default_memory_mb = GetDefaultMemoryMB(); + size_t memory_cap_mb = base::SysInfo::AmountOfPhysicalMemoryMB() / 4; + if (mb_limit_when_visible > memory_cap_mb) { + mb_limit_when_visible = memory_cap_mb; + } else if (mb_limit_when_visible < default_memory_mb) { + mb_limit_when_visible = default_memory_mb; + } + + actual.bytes_limit_when_visible = mb_limit_when_visible * 1024 * 1024; + } else { + // Ignore what the system said and give all clients the same maximum + // allocation on desktop platforms. + actual.bytes_limit_when_visible = 512 * 1024 * 1024; + actual.priority_cutoff_when_visible = + gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; + + // For large monitors (4k), double the tile memory to avoid frequent out of + // memory problems. 4k could mean a screen width of anywhere from 3840 to + // 4096 (see https://en.wikipedia.org/wiki/4K_resolution). We use 3500 as a + // proxy for "large enough". + static const int kLargeDisplayThreshold = 3500; + int display_width = + std::round(initial_screen_size.width() * initial_device_scale_factor); + if (display_width >= kLargeDisplayThreshold) { + actual.bytes_limit_when_visible *= 2; + } } - - actual.bytes_limit_when_visible = mb_limit_when_visible * 1024 * 1024; #else // Ignore what the system said and give all clients the same maximum // allocation on desktop platforms.
diff --git a/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc b/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc index 18e6791..70e1eb7b 100644 --- a/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc +++ b/third_party/blink/renderer/platform/widget/input/frame_widget_input_handler_impl.cc
@@ -230,12 +230,14 @@ } void FrameWidgetInputHandlerImpl::CopyToFindPboard() { +#if BUILDFLAG(IS_MAC) RunOnMainThread(base::BindOnce( [](base::WeakPtr<mojom::blink::FrameWidgetInputHandler> handler) { if (handler) handler->CopyToFindPboard(); }, main_thread_frame_widget_input_handler_)); +#endif } void FrameWidgetInputHandlerImpl::CenterSelection() {
diff --git a/third_party/blink/tools/blinkpy/common/system/command_line.py b/third_party/blink/tools/blinkpy/common/system/command_line.py new file mode 100644 index 0000000..84a4d2c --- /dev/null +++ b/third_party/blink/tools/blinkpy/common/system/command_line.py
@@ -0,0 +1,39 @@ +# 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. +"""Common argument parsing library for `blinkpy`.""" + +import argparse +import functools +import shutil +from typing import ClassVar, Optional + + +class ArgumentParser(argparse.ArgumentParser): + """Argument parser with neater default formatting.""" + + MAX_WIDTH: ClassVar[int] = 100 + + def __init__(self, *args, width: Optional[int] = None, **kwargs): + if not width: + fallback = self.MAX_WIDTH, 1 + width = shutil.get_terminal_size(fallback).columns + width = min(width, self.MAX_WIDTH) + formatter_class = functools.partial( + argparse.HelpFormatter, + width=width, + # `max_help_position` measures the left-side margin before the help + # message begins: + # --flag Flag help + # <- max_help_position -> + # + # Pick a relatively large default `max_help_position` to make enough + # space for the flag and try to fit the entry on one line, instead + # of breaking like: + # --flag + # Flag help + # + # This also keeps the help message narrow. + max_help_position=int(0.4 * width)) + kwargs.setdefault('formatter_class', formatter_class) + super().__init__(*args, **kwargs)
diff --git a/third_party/blink/tools/blinkpy/common/wpt_results_diff.py b/third_party/blink/tools/blinkpy/common/wpt_results_diff.py index ecbcb2f..64939f0 100644 --- a/third_party/blink/tools/blinkpy/common/wpt_results_diff.py +++ b/third_party/blink/tools/blinkpy/common/wpt_results_diff.py
@@ -25,15 +25,11 @@ """ -def wpt_results_diff(actual: TestNode, - expected: Optional[TestNode] = None, - test_type: str = 'testharness'): +def wpt_results_diff(actual: TestNode, expected: Optional[TestNode] = None): if not expected: expected = wpt_metadata.make_empty_test(actual) - wpt_metadata.fill_implied_expectations(expected, set(actual.subtests), - test_type) - wpt_metadata.fill_implied_expectations(actual, set(expected.subtests), - test_type) + wpt_metadata.fill_implied_expectations(expected, set(actual.subtests)) + wpt_metadata.fill_implied_expectations(actual, set(expected.subtests)) return _TEMPLATE % WPTResultsDiffGenerator().generate_tbody( expected, actual)
diff --git a/third_party/blink/tools/blinkpy/w3c/import_notifier.py b/third_party/blink/tools/blinkpy/w3c/import_notifier.py index a963b8f..29c19b5 100644 --- a/third_party/blink/tools/blinkpy/w3c/import_notifier.py +++ b/third_party/blink/tools/blinkpy/w3c/import_notifier.py
@@ -179,7 +179,7 @@ continue test_type = manifest.get_test_type( self.finder.strip_wpt_path(test_path)) - # TODO(crbug.com/1464051): After the switch to wptrunner, change the + # TODO(crbug.com/1474702): After the switch to wptrunner, change the # condition to just `if not test_type` to check for failures in # metadata for other test types. Then, remove the other `examine_*` # methods. @@ -232,11 +232,9 @@ if not test_before: test_before = wpt_metadata.make_empty_test(test_after) wpt_metadata.fill_implied_expectations(test_before, - set(test_after.subtests), - test_before.test_type) + set(test_after.subtests)) wpt_metadata.fill_implied_expectations(test_after, - set(test_before.subtests), - test_after.test_type) + set(test_before.subtests)) assert set(test_before.subtests) == set(test_after.subtests) nodes = [(test_before, test_after)] nodes.extend((
diff --git a/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py b/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py index 8d8b3a1..c04e75a 100644 --- a/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/import_notifier_unittest.py
@@ -368,7 +368,7 @@ self.notifier.examine_metadata_changes( 'https://crrev.com/c/12345/3/') - # TODO(crbug.com/1464051): After the switch to wptrunner, check that + # TODO(crbug.com/1474702): After the switch to wptrunner, check that # non-wdspec tests can generate failures (i.e., delete the first # assertion, and turn the second one into `assertEqual`). For now, # require that no such failures are generated.
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_metadata.py b/third_party/blink/tools/blinkpy/w3c/wpt_metadata.py index e35f04ea..c53a8d9 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_metadata.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_metadata.py
@@ -43,19 +43,16 @@ def fill_implied_expectations(test: TestNode, - extra_subtests: Optional[Set[str]] = None, - test_type: str = 'testharness'): + extra_subtests: Optional[Set[str]] = None): """Populate a test result with implied OK/PASS expectations. This is a helper for diffing WPT results. """ - # TODO(crbug.com/1464051): Replace the `test_type` argument with - # `test.test_type`. default_expected = default_expected_by_type() - _ensure_expectation(test, default_expected[test_type, False]) + _ensure_expectation(test, default_expected[test.test_type, False]) for subtest in test.subtests: _ensure_expectation(test.get_subtest(subtest), - default_expected[test_type, True]) + default_expected[test.test_type, True]) missing_subtests = (extra_subtests or set()) - set(test.subtests) for subtest in missing_subtests: subtest_node = SubtestNode(wptnode.DataNode(subtest))
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_metadata_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_metadata_unittest.py index 2c00195..2b4b84b 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_metadata_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_metadata_unittest.py
@@ -27,9 +27,8 @@ [test.html] [subtest] """) - wpt_metadata.fill_implied_expectations(test, {'extra-subtest'}, - 'testharness') - + test.set('type', 'testharness') + wpt_metadata.fill_implied_expectations(test, {'extra-subtest'}) self.assertEqual(test.expected, 'OK') self.assertEqual(test.known_intermittent, []) self.assertEqual(set(test.subtests), {'subtest', 'extra-subtest'}) @@ -43,7 +42,8 @@ test = _compile(b"""\ [test.html] """) - wpt_metadata.fill_implied_expectations(test, test_type='reftest') + test.set('type', 'reftest') + wpt_metadata.fill_implied_expectations(test) self.assertEqual(test.expected, 'PASS') self.assertEqual(test.known_intermittent, []) @@ -54,6 +54,7 @@ [subtest] expected: FAIL """) + test.set('type', 'testharness') wpt_metadata.fill_implied_expectations(test) self.assertEqual(test.expected, 'ERROR') self.assertEqual(test.known_intermittent, ['OK'])
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py index cb1e54d..e1fca0e 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
@@ -725,8 +725,10 @@ if not test_type: raise EventProcessingError(f'Unknown test type: {result.name!r}') actual = result.test_section(self.run_info) - html_diff_content = wpt_results_diff.wpt_results_diff( - actual, expected, test_type) + actual.set('type', test_type) + if expected: + expected.set('type', test_type) + html_diff_content = wpt_results_diff.wpt_results_diff(actual, expected) html_diff_subpath = self.port.output_filename( result.name, test_failures.FILENAME_SUFFIX_HTML_DIFF, '.html')
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/factory.py b/third_party/blink/tools/blinkpy/web_tests/port/factory.py index 8a798b7..1305060 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/factory.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/factory.py
@@ -147,29 +147,26 @@ def configuration_options(): return [ - optparse.make_option( - '--debug', - action='store_const', - const='Debug', - dest='configuration', - help='Set the configuration to Debug'), + optparse.make_option('--debug', + action='store_const', + const='Debug', + dest='configuration', + help='Set the configuration to Debug'), optparse.make_option( '-t', '--target', dest='target', - help='Specify the target build subdirectory under src/out/'), - optparse.make_option( - '--release', - action='store_const', - const='Release', - dest='configuration', - help='Set the configuration to Release'), - optparse.make_option( - '--no-xvfb', - action='store_false', - dest='use_xvfb', - default=True, - help='Do not run tests with Xvfb'), + help='Specify the target build subdirectory under //out/'), + optparse.make_option('--release', + action='store_const', + const='Release', + dest='configuration', + help='Set the configuration to Release'), + optparse.make_option('--no-xvfb', + action='store_false', + dest='use_xvfb', + default=True, + help='Do not run tests with Xvfb'), ] @@ -235,6 +232,7 @@ help=('Do not run the browser headlessly; pause after each test ' 'until the window is closed. On Linux, do not start Xvfb.')) group.add_argument('--webdriver-binary', + metavar='PATH', type=str, help='Alternate path of the webdriver binary.') group.add_argument( @@ -255,6 +253,7 @@ results_group.add_argument( '--additional-driver-flag', '--additional-drt-flag', + metavar='FLAG', dest='additional_driver_flag', action='append', default=[], @@ -262,6 +261,7 @@ 'Specify multiple times to add multiple flags.')) results_group.add_argument( '--build-directory', + metavar='PATH', default='out', help=( 'Path to the directory where build files are kept, not including ' @@ -274,9 +274,11 @@ '--json-test-results', # New name from json_results_generator '--write-full-results-to', # Old argument name '--isolated-script-test-output', # Isolated API + metavar='PATH', help='Path to write the JSON test results for *all* tests.') results_group.add_argument( '--write-run-histories-to', + metavar='PATH', help='Path to write the JSON test run histories.') results_group.add_argument( '--no-show-results', @@ -284,6 +286,7 @@ action='store_false', help="Don't launch a browser with results after the tests are done") results_group.add_argument('--results-directory', + metavar='PATH', help='Location of test results') results_group.add_argument('--smoke', action='store_true', @@ -355,13 +358,14 @@ testing_group = parser.add_argument_group('Testing Options') testing_group.add_argument( '--additional-env-var', + metavar='NAME=VALUE', action='append', default=[], - help=('Passes that environment variable to the tests ' - '(--additional-env-var=NAME=VALUE)')) + help='Pass an environment variable NAME to the test driver.') testing_group.add_argument('--child-processes', '--jobs', '-j', + metavar='N', type=int, help='Number of drivers to run in parallel.') testing_group.add_argument( @@ -374,11 +378,13 @@ help='Only alert on sanitizer-related errors and crashes') testing_group.add_argument( '--exit-after-n-crashes-or-timeouts', + metavar='N', type=int, default=None, help='Exit after the first N crashes instead of running all tests') testing_group.add_argument( '--exit-after-n-failures', + metavar='N', type=int, default=None, help='Exit after the first N failures instead of running all tests') @@ -387,11 +393,13 @@ '--isolated-script-test-repeat', # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it. '--gtest_repeat', + metavar='N', type=int, default=1, help='Number of times to run the set of tests (e.g. ABCABCABC)') testing_group.add_argument( '--repeat-each', + metavar='N', type=int, default=1, help='Number of times to run each test (e.g. AAABBBCCC)') @@ -399,6 +407,7 @@ '--num-retries', '--test-launcher-retry-limit', '--isolated-script-test-launcher-retry-limit', + metavar='N', type=int, default=None, help=('Number of times to retry failures. Default (when this ' @@ -414,6 +423,7 @@ help="Don't retry any failures (equivalent to --num-retries=0).") testing_group.add_argument( '--total-shards', + metavar='SHARDS', type=int, help=('Total number of shards being used for this test run. ' 'Must be used with --shard-index. ' @@ -421,6 +431,7 @@ 'all of the shards.)')) testing_group.add_argument( '--shard-index', + metavar='INDEX', type=int, help=('Shard index [0..total_shards) of this test run. ' 'Must be used with --total-shards.')) @@ -636,15 +647,21 @@ 'testharness test failures will be shown, even if the ' 'failures are expected in *-expected.txt.')) else: + test_types = [ + 'testharness', + 'reftest', + 'wdspec', + 'crashtest', + 'print-reftest', + 'manual', + ] testing_group.add_argument( '--test-types', nargs='*', - choices=[ - 'testharness', 'reftest', 'wdspec', 'crashtest', - 'print-reftest', 'manual' - ], + choices=test_types, default=['testharness', 'reftest', 'crashtest', 'print-reftest'], - help='Test types to run') + metavar='TYPE', + help=f'Test types to run (choices: {", ".join(test_types)})') testing_group.add_argument('--no-wpt-internal', action='store_false', dest='run_wpt_internal', @@ -653,12 +670,15 @@ # for run_wpt_tests.py only def add_android_options_group(parser: argparse.ArgumentParser): - group = parser.add_argument_group('Android Options') + group = parser.add_argument_group( + 'Android Options', + 'Options for configuring Android devices and tooling. ' + 'Ignored for non-Android products.') group.add_argument( '--avd-config', help=('Path to the avd config. Used by the test runner to launch ' 'Android emulators. Required when there is no android ' - 'emulators running, or no devices connected to the system.' + 'emulators running, or no devices connected to the system. ' '(See //tools/android/avd/proto for message definition ' 'and existing *.textpb files.)')) group.add_argument('--emulator-window', @@ -666,17 +686,20 @@ help='Enable graphical window display on the emulator.') group.add_argument( '--browser-apk', - help= - ('Specify path under src/out/ of the browser APK to install and run. ' - 'For WebView, this should point to the shell. ' - 'The default value is apks/ChromePublic.apk for Chrome Android, ' - 'and apks/SystemWebViewShell.apk for WebView.')) + metavar='APK', + help=( + 'Specify path under //out/ of the browser APK to install and run. ' + 'For WebView, this should point to the shell. ' + 'The default value is apks/ChromePublic.apk for Chrome Android, ' + 'and apks/SystemWebViewShell.apk for WebView.')) group.add_argument( '--webview-provider', - help= - ('Specify path under src/out/ of the WebView provider APK to install. ' - 'The default value is apks/SystemWebView.apk.')) + metavar='PATH', + help=( + 'Specify path under //out/ of the WebView provider APK to install. ' + 'The default value is apks/SystemWebView.apk.')) group.add_argument('--additional-apk', + metavar='APK', type=os.path.abspath, action='append', default=[], @@ -689,21 +712,24 @@ def add_ios_options_group(parser: argparse.ArgumentParser): - group = parser.add_argument_group('iOS Options') + group = parser.add_argument_group( + 'iOS Options', 'Options for configuring iOS devices and tooling. ' + 'Ignored for non-`chrome_ios` products.') group.add_argument('--xcode-build-version', - help='Xcode build version to install. Use chrome_ios' - ' product to enable this', - metavar='build_id') + help='Xcode build version to install.', + metavar='VERSION') return group def add_logging_options_group(parser: argparse.ArgumentParser): group = parser.add_argument_group('Logging Options') - group.add_argument('-v', - '--verbose', - action='count', - default=0, - help='Increase verbosity'), + group.add_argument( + '-v', + '--verbose', + action='count', + default=0, + help=('Increase verbosity (may provide multiple times). ' + 'Providing at least once will dump browser logs.')), # TODO: when using run_wpt_tests.py on swarming, we should run # that inside run_isolated_script_test.py so that we can remove # the workaround below
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py index 7731600..46f737d 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -35,6 +35,7 @@ from blinkpy.common import exit_codes from blinkpy.common.host import Host +from blinkpy.common.system import command_line from blinkpy.web_tests.controllers.manager import Manager from blinkpy.web_tests.models import test_run_results from blinkpy.web_tests.port import factory @@ -85,7 +86,7 @@ def parse_args(args): - parser = argparse.ArgumentParser( + parser = command_line.ArgumentParser( usage='%(prog)s [options] [tests]', description=('Runs Blink web tests as described in ' '//docs/testing/web_tests.md'))
diff --git a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py index f0fc87b..180bf34d 100644 --- a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py +++ b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py
@@ -1,9 +1,8 @@ # 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. -"""Run web platform tests for Chromium-related products.""" +r"""Run web platform tests as described in //docs/testing/web_platform_tests_wptrunner.md""" -import argparse import contextlib import functools import json @@ -20,6 +19,7 @@ from blinkpy.common import exit_codes from blinkpy.common import path_finder from blinkpy.common.host import Host +from blinkpy.common.system import command_line from blinkpy.w3c.wpt_results_processor import WPTResultsProcessor from blinkpy.web_tests.controllers.web_test_finder import WebTestFinder from blinkpy.web_tests.port.base import Port @@ -621,10 +621,8 @@ def parse_arguments(argv): - parser = argparse.ArgumentParser( - usage='%(prog)s [options] [tests]', - description=('Runs WPT tests as described in ' - '//docs/testing/web_platform_tests_wptrunner.md')) + parser = command_line.ArgumentParser(usage='%(prog)s [options] [tests]', + description=__doc__.splitlines()[0]) factory.add_configuration_options_group(parser, rwt=False, product_choices=list(
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 0ab409a..15130a81 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -4218,8 +4218,6 @@ crbug.com/996219 [ Win ] virtual/text-antialias/emoji-vertical-origin-visual.html [ Failure ] -crbug.com/1015130 external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html [ Failure Pass ] - crbug.com/1000051 media/controls/volume-slider.html [ Failure Pass Timeout ] # Test for LCP's mouseover heuristics. Tested only under virtual/lcp-mouseover-heuristics. @@ -5744,6 +5742,8 @@ crbug.com/1459038 [ Linux ] external/wpt/webmidi/idlharness.https.window.html [ Failure ] +crbug.com/1446799 external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html [ Failure Pass ] + # These tests are optional and not reliably supported in Chrome. crbug.com/1370307 [ Release Win ] external/wpt/encoding-detection/ar-ISO-8859-6-late.tentative.html [ Failure Pass ] crbug.com/1370307 external/wpt/encoding-detection/ar-windows-1256-late.tentative.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt index be758f7..1e3f2634 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-computed-relative-color-expected.txt
@@ -1,965 +1,965 @@ This is a testharness.js-based test. -Found 961 tests; 0 PASS, 961 FAIL, 0 TIMEOUT, 0 NOTRUN. -FAIL Property color value 'rgb(from rebeccapurple r g b)' assert_true: 'rgb(from rebeccapurple r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g b / alpha)' assert_true: 'rgb(from rebeccapurple r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)' assert_true: 'rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(from rebeccapurple r g b) r g b)' assert_true: 'rgb(from rgb(from rebeccapurple r g b) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from color(display-p3 0 1 0) r g b / alpha)' assert_true: 'rgb(from color(display-p3 0 1 0) r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from lab(100 104.3 -50.9) r g b)' assert_true: 'rgb(from lab(100 104.3 -50.9) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from lab(0 104.3 -50.9) r g b)' assert_true: 'rgb(from lab(0 104.3 -50.9) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from lch(100 116 334) r g b)' assert_true: 'rgb(from lch(100 116 334) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from lch(0 116 334) r g b)' assert_true: 'rgb(from lch(0 116 334) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from oklab(1 0.365 -0.16) r g b)' assert_true: 'rgb(from oklab(1 0.365 -0.16) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from oklab(0 0.365 -0.16) r g b)' assert_true: 'rgb(from oklab(0 0.365 -0.16) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from oklch(1 0.399 336.3) r g b)' assert_true: 'rgb(from oklch(1 0.399 336.3) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from oklch(0 0.399 336.3) r g b)' assert_true: 'rgb(from oklch(0 0.399 336.3) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 0 0 0)' assert_true: 'rgb(from rebeccapurple 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 0 0 0 / 0)' assert_true: 'rgb(from rebeccapurple 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 0 g b / alpha)' assert_true: 'rgb(from rebeccapurple 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r 0 b / alpha)' assert_true: 'rgb(from rebeccapurple r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g 0 / alpha)' assert_true: 'rgb(from rebeccapurple r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g b / 0)' assert_true: 'rgb(from rebeccapurple r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 25 g b / alpha)' assert_true: 'rgb(from rebeccapurple 25 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r 25 b / alpha)' assert_true: 'rgb(from rebeccapurple r 25 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g 25 / alpha)' assert_true: 'rgb(from rebeccapurple r g 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g b / .25)' assert_true: 'rgb(from rebeccapurple r g b / .25)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 20% g b / alpha)' assert_true: 'rgb(from rebeccapurple 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r 20% b / alpha)' assert_true: 'rgb(from rebeccapurple r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g 20% / alpha)' assert_true: 'rgb(from rebeccapurple r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g b / 20%)' assert_true: 'rgb(from rebeccapurple r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 25 g b / 25%)' assert_true: 'rgb(from rebeccapurple 25 g b / 25%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r 25 b / 25%)' assert_true: 'rgb(from rebeccapurple r 25 b / 25%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g 25 / 25%)' assert_true: 'rgb(from rebeccapurple r g 25 / 25%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple g b r)' assert_true: 'rgb(from rebeccapurple g b r)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple b alpha r / g)' assert_true: 'rgb(from rebeccapurple b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r r r / r)' assert_true: 'rgb(from rebeccapurple r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple alpha alpha alpha / alpha)' assert_true: 'rgb(from rebeccapurple alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) g b r)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) g b r)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r 20% 10)' assert_true: 'rgb(from rebeccapurple r 20% 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r 10 20%)' assert_true: 'rgb(from rebeccapurple r 10 20%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple 0% 10 10)' assert_true: 'rgb(from rebeccapurple 0% 10 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple calc(r) calc(g) calc(b))' assert_true: 'rgb(from rebeccapurple calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r calc(g * 2) 10)' assert_true: 'rgb(from rebeccapurple r calc(g * 2) 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple b calc(r * .5) 10)' assert_true: 'rgb(from rebeccapurple b calc(r * .5) 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)' assert_true: 'rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)' assert_true: 'rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple none none none)' assert_true: 'rgb(from rebeccapurple none none none)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple none none none / none)' assert_true: 'rgb(from rebeccapurple none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g none)' assert_true: 'rgb(from rebeccapurple r g none)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g none / alpha)' assert_true: 'rgb(from rebeccapurple r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rebeccapurple r g b / none)' assert_true: 'rgb(from rebeccapurple r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)' assert_true: 'rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20% 40% 60% / 80%) r g b / none)' assert_true: 'rgb(from rgb(20% 40% 60% / 80%) r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(none none none) r g b)' assert_true: 'rgb(from rgb(none none none) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(none none none / none) r g b / alpha)' assert_true: 'rgb(from rgb(none none none / none) r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20% none 60%) r g b)' assert_true: 'rgb(from rgb(20% none 60%) r g b)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from rgb(20% 40% 60% / none) r g b / alpha)' assert_true: 'rgb(from rgb(20% 40% 60% / none) r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s l)' assert_true: 'hsl(from rebeccapurple h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s l / alpha)' assert_true: 'hsl(from rebeccapurple h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)' assert_true: 'hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(from rebeccapurple h s l) h s l)' assert_true: 'hsl(from hsl(from rebeccapurple h s l) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from color(display-p3 0 1 0) h s l / alpha)' assert_true: 'hsl(from color(display-p3 0 1 0) h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from lab(100 104.3 -50.9) h s l)' assert_true: 'hsl(from lab(100 104.3 -50.9) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from lab(0 104.3 -50.9) h s l)' assert_true: 'hsl(from lab(0 104.3 -50.9) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from lch(100 116 334) h s l)' assert_true: 'hsl(from lch(100 116 334) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from lch(0 116 334) h s l)' assert_true: 'hsl(from lch(0 116 334) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from oklab(1 0.365 -0.16) h s l)' assert_true: 'hsl(from oklab(1 0.365 -0.16) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from oklab(0 0.365 -0.16) h s l)' assert_true: 'hsl(from oklab(0 0.365 -0.16) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from oklch(1 0.399 336.3) h s l)' assert_true: 'hsl(from oklch(1 0.399 336.3) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from oklch(0 0.399 336.3) h s l)' assert_true: 'hsl(from oklch(0 0.399 336.3) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 0 0% 0%)' assert_true: 'hsl(from rebeccapurple 0 0% 0%)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 0deg 0% 0%)' assert_true: 'hsl(from rebeccapurple 0deg 0% 0%)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 0 0% 0% / 0)' assert_true: 'hsl(from rebeccapurple 0 0% 0% / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 0deg 0% 0% / 0)' assert_true: 'hsl(from rebeccapurple 0deg 0% 0% / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 0 s l / alpha)' assert_true: 'hsl(from rebeccapurple 0 s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 0deg s l / alpha)' assert_true: 'hsl(from rebeccapurple 0deg s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h 0% l / alpha)' assert_true: 'hsl(from rebeccapurple h 0% l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s 0% / alpha)' assert_true: 'hsl(from rebeccapurple h s 0% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s l / 0)' assert_true: 'hsl(from rebeccapurple h s l / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 25 s l / alpha)' assert_true: 'hsl(from rebeccapurple 25 s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple 25deg s l / alpha)' assert_true: 'hsl(from rebeccapurple 25deg s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h 20% l / alpha)' assert_true: 'hsl(from rebeccapurple h 20% l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s 20% / alpha)' assert_true: 'hsl(from rebeccapurple h s 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s l / .25)' assert_true: 'hsl(from rebeccapurple h s l / .25)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h l s)' assert_true: 'hsl(from rebeccapurple h l s)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h alpha l / s)' assert_true: 'hsl(from rebeccapurple h alpha l / s)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h l l / l)' assert_true: 'hsl(from rebeccapurple h l l / l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h alpha alpha / alpha)' assert_true: 'hsl(from rebeccapurple h alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h l s)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h l s)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple calc(h) calc(s) calc(l))' assert_true: 'hsl(from rebeccapurple calc(h) calc(s) calc(l))' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))' assert_true: 'hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple none none none)' assert_true: 'hsl(from rebeccapurple none none none)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple none none none / none)' assert_true: 'hsl(from rebeccapurple none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s none)' assert_true: 'hsl(from rebeccapurple h s none)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s none / alpha)' assert_true: 'hsl(from rebeccapurple h s none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple h s l / none)' assert_true: 'hsl(from rebeccapurple h s l / none)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from rebeccapurple none s l / alpha)' assert_true: 'hsl(from rebeccapurple none s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)' assert_true: 'hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(120deg 20% 50% / .5) h s l / none)' assert_true: 'hsl(from hsl(120deg 20% 50% / .5) h s l / none)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)' assert_true: 'hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(none none none) h s l)' assert_true: 'hsl(from hsl(none none none) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(none none none / none) h s l / alpha)' assert_true: 'hsl(from hsl(none none none / none) h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(120deg none 50% / .5) h s l)' assert_true: 'hsl(from hsl(120deg none 50% / .5) h s l)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(120deg 20% 50% / none) h s l / alpha)' assert_true: 'hsl(from hsl(120deg 20% 50% / none) h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hsl(from hsl(none 20% 50% / .5) h s l / alpha)' assert_true: 'hsl(from hsl(none 20% 50% / .5) h s l / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w b)' assert_true: 'hwb(from rebeccapurple h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w b / alpha)' assert_true: 'hwb(from rebeccapurple h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)' assert_true: 'hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(from rebeccapurple h w b) h w b)' assert_true: 'hwb(from hwb(from rebeccapurple h w b) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from color(display-p3 0 1 0) h w b / alpha)' assert_true: 'hwb(from color(display-p3 0 1 0) h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from lab(100 104.3 -50.9) h w b)' assert_true: 'hwb(from lab(100 104.3 -50.9) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from lab(0 104.3 -50.9) h w b)' assert_true: 'hwb(from lab(0 104.3 -50.9) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from lch(100 116 334) h w b)' assert_true: 'hwb(from lch(100 116 334) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from lch(0 116 334) h w b)' assert_true: 'hwb(from lch(0 116 334) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from oklab(1 0.365 -0.16) h w b)' assert_true: 'hwb(from oklab(1 0.365 -0.16) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from oklab(0 0.365 -0.16) h w b)' assert_true: 'hwb(from oklab(0 0.365 -0.16) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from oklch(1 0.399 336.3) h w b)' assert_true: 'hwb(from oklch(1 0.399 336.3) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from oklch(0 0.399 336.3) h w b)' assert_true: 'hwb(from oklch(0 0.399 336.3) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 0 0% 0%)' assert_true: 'hwb(from rebeccapurple 0 0% 0%)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 0deg 0% 0%)' assert_true: 'hwb(from rebeccapurple 0deg 0% 0%)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 0 0% 0% / 0)' assert_true: 'hwb(from rebeccapurple 0 0% 0% / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 0deg 0% 0% / 0)' assert_true: 'hwb(from rebeccapurple 0deg 0% 0% / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 0 w b / alpha)' assert_true: 'hwb(from rebeccapurple 0 w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 0deg w b / alpha)' assert_true: 'hwb(from rebeccapurple 0deg w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h 0% b / alpha)' assert_true: 'hwb(from rebeccapurple h 0% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w 0% / alpha)' assert_true: 'hwb(from rebeccapurple h w 0% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w b / 0)' assert_true: 'hwb(from rebeccapurple h w b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 25 w b / alpha)' assert_true: 'hwb(from rebeccapurple 25 w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple 25deg w b / alpha)' assert_true: 'hwb(from rebeccapurple 25deg w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h 20% b / alpha)' assert_true: 'hwb(from rebeccapurple h 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w 20% / alpha)' assert_true: 'hwb(from rebeccapurple h w 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w b / .2)' assert_true: 'hwb(from rebeccapurple h w b / .2)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h b w)' assert_true: 'hwb(from rebeccapurple h b w)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h alpha w / b)' assert_true: 'hwb(from rebeccapurple h alpha w / b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w w / w)' assert_true: 'hwb(from rebeccapurple h w w / w)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h alpha alpha / alpha)' assert_true: 'hwb(from rebeccapurple h alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h b w)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h b w)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple calc(h) calc(w) calc(b))' assert_true: 'hwb(from rebeccapurple calc(h) calc(w) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))' assert_true: 'hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple none none none)' assert_true: 'hwb(from rebeccapurple none none none)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple none none none / none)' assert_true: 'hwb(from rebeccapurple none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w none)' assert_true: 'hwb(from rebeccapurple h w none)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w none / alpha)' assert_true: 'hwb(from rebeccapurple h w none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple h w b / none)' assert_true: 'hwb(from rebeccapurple h w b / none)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from rebeccapurple none w b / alpha)' assert_true: 'hwb(from rebeccapurple none w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)' assert_true: 'hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(120deg 20% 50% / .5) h w b / none)' assert_true: 'hwb(from hwb(120deg 20% 50% / .5) h w b / none)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)' assert_true: 'hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(none none none) h w b)' assert_true: 'hwb(from hwb(none none none) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(none none none / none) h w b / alpha)' assert_true: 'hwb(from hwb(none none none / none) h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(120deg none 50% / .5) h w b)' assert_true: 'hwb(from hwb(120deg none 50% / .5) h w b)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(120deg 20% 50% / none) h w b / alpha)' assert_true: 'hwb(from hwb(120deg 20% 50% / none) h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'hwb(from hwb(none 20% 50% / .5) h w b / alpha)' assert_true: 'hwb(from hwb(none 20% 50% / .5) h w b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a b)' assert_true: 'lab(from lab(25 20 50) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a b / alpha)' assert_true: 'lab(from lab(25 20 50) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a b / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(200 300 400 / 500%) l a b / alpha)' assert_true: 'lab(from lab(200 300 400 / 500%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(-200 -300 -400 / -500%) l a b / alpha)' assert_true: 'lab(from lab(-200 -300 -400 / -500%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(from lab(25 20 50) l a b) l a b)' assert_true: 'lab(from lab(from lab(25 20 50) l a b) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from color(display-p3 0 0 0) l a b / alpha)' assert_true: 'lab(from color(display-p3 0 0 0) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) 0 0 0)' assert_true: 'lab(from lab(25 20 50) 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) 0 0 0 / 0)' assert_true: 'lab(from lab(25 20 50) 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) 0 a b / alpha)' assert_true: 'lab(from lab(25 20 50) 0 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l 0 b / alpha)' assert_true: 'lab(from lab(25 20 50) l 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a 0 / alpha)' assert_true: 'lab(from lab(25 20 50) l a 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a b / 0)' assert_true: 'lab(from lab(25 20 50) l a b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) 0 a b / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) 0 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l 0 b / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) l 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a 0 / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) l a 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a b / 0)' assert_true: 'lab(from lab(25 20 50 / 40%) l a b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) 35 a b / alpha)' assert_true: 'lab(from lab(25 20 50) 35 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l 35 b / alpha)' assert_true: 'lab(from lab(25 20 50) l 35 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a 35 / alpha)' assert_true: 'lab(from lab(25 20 50) l a 35 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a b / .35)' assert_true: 'lab(from lab(25 20 50) l a b / .35)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) 35 a b / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) 35 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l 35 b / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) l 35 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a 35 / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) l a 35 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a b / .35)' assert_true: 'lab(from lab(25 20 50 / 40%) l a b / .35)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(0.7 45 30 / 40%) 200 300 400 / 500)' assert_true: 'lab(from lab(0.7 45 30 / 40%) 200 300 400 / 500)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(0.7 45 30 / 40%) -200 -300 -400 / -500)' assert_true: 'lab(from lab(0.7 45 30 / 40%) -200 -300 -400 / -500)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l b a)' assert_true: 'lab(from lab(25 20 50) l b a)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a a / a)' assert_true: 'lab(from lab(25 20 50) l a a / a)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l b a)' assert_true: 'lab(from lab(25 20 50 / 40%) l b a)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a a / a)' assert_true: 'lab(from lab(25 20 50 / 40%) l a a / a)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) calc(l) calc(a) calc(b))' assert_true: 'lab(from lab(25 20 50) calc(l) calc(a) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' assert_true: 'lab(from lab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) none none none)' assert_true: 'lab(from lab(25 20 50) none none none)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) none none none / none)' assert_true: 'lab(from lab(25 20 50) none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a none)' assert_true: 'lab(from lab(25 20 50) l a none)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a none / alpha)' assert_true: 'lab(from lab(25 20 50) l a none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50) l a b / none)' assert_true: 'lab(from lab(25 20 50) l a b / none)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a none / alpha)' assert_true: 'lab(from lab(25 20 50 / 40%) l a none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / 40%) l a b / none)' assert_true: 'lab(from lab(25 20 50 / 40%) l a b / none)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(none none none) l a b)' assert_true: 'lab(from lab(none none none) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(none none none / none) l a b / alpha)' assert_true: 'lab(from lab(none none none / none) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 none 50) l a b)' assert_true: 'lab(from lab(25 none 50) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(25 20 50 / none) l a b / alpha)' assert_true: 'lab(from lab(25 20 50 / none) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(2 3 4 / 500%) l a b / alpha)' assert_true: 'oklab(from oklab(2 3 4 / 500%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)' assert_true: 'oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)' assert_true: 'oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from color(display-p3 0 0 0) l a b / alpha)' assert_true: 'oklab(from color(display-p3 0 0 0) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / .35)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / .35)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)' assert_true: 'oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)' assert_true: 'oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l b a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l b a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a a / a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a a / a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))' assert_true: 'oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) none none none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none / none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5) l a b / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(none none none) l a b)' assert_true: 'oklab(from oklab(none none none) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(none none none / none) l a b / alpha)' assert_true: 'oklab(from oklab(none none none / none) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 none 0.5) l a b)' assert_true: 'oklab(from oklab(0.25 none 0.5) l a b)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)' assert_true: 'oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(.7 45 30) alpha b a / l)' assert_true: 'lab(from lab(.7 45 30) alpha b a / l)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(.7 45 30) alpha a b / alpha)' assert_true: 'lab(from lab(.7 45 30) alpha a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(.7 45 30) alpha a a / alpha)' assert_true: 'lab(from lab(.7 45 30) alpha a a / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha b a / l)' assert_true: 'lab(from lab(.7 45 30 / 40%) alpha b a / l)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha a b / alpha)' assert_true: 'lab(from lab(.7 45 30 / 40%) alpha a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha a a / alpha)' assert_true: 'lab(from lab(.7 45 30 / 40%) alpha a a / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha b a / l)' assert_true: 'oklab(from oklab(.7 0.45 0.3) alpha b a / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)' assert_true: 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)' assert_true: 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c h)' assert_true: 'lch(from lch(0.7 45 30) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c h / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(200 300 400 / 500%) l c h / alpha)' assert_true: 'lch(from lch(200 300 400 / 500%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(-200 -300 -400 / -500%) l c h / alpha)' assert_true: 'lch(from lch(-200 -300 -400 / -500%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(from lch(0.7 45 30) l c h) l c h)' assert_true: 'lch(from lch(from lch(0.7 45 30) l c h) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from color(display-p3 0 0 0) l c h / alpha)' assert_true: 'lch(from color(display-p3 0 0 0) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lab(0.7 45 30) l c h / alpha)' assert_true: 'lch(from lab(0.7 45 30) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) 0 0 0)' assert_true: 'lch(from lch(0.7 45 30) 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) 0 0 0deg)' assert_true: 'lch(from lch(0.7 45 30) 0 0 0deg)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) 0 0 0 / 0)' assert_true: 'lch(from lch(0.7 45 30) 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) 0 0 0deg / 0)' assert_true: 'lch(from lch(0.7 45 30) 0 0 0deg / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) 0 c h / alpha)' assert_true: 'lch(from lch(0.7 45 30) 0 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l 0 h / alpha)' assert_true: 'lch(from lch(0.7 45 30) l 0 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c 0 / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c 0deg / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c 0deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c h / 0)' assert_true: 'lch(from lch(0.7 45 30) l c h / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) 0 c h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) 0 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l 0 h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l 0 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c 0 / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c 0deg / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c 0deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / 0)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c h / 0)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) 25 c h / alpha)' assert_true: 'lch(from lch(0.7 45 30) 25 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l 25 h / alpha)' assert_true: 'lch(from lch(0.7 45 30) l 25 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c 25 / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c 25deg / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c 25deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c h / .25)' assert_true: 'lch(from lch(0.7 45 30) l c h / .25)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) 25 c h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) 25 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l 25 h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l 25 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c 25 / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c 25deg / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c 25deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / .25)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c h / .25)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)' assert_true: 'lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) -200 -300 -400 / -500)' assert_true: 'lch(from lch(0.7 45 30 / 40%) -200 -300 -400 / -500)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) 50 120 400deg / 500)' assert_true: 'lch(from lch(0.7 45 30 / 40%) 50 120 400deg / 500)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) 50 120 -400deg / -500)' assert_true: 'lch(from lch(0.7 45 30 / 40%) 50 120 -400deg / -500)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30) l c c / alpha)' assert_true: 'lch(from lch(.7 45 30) l c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30 / 40%) l c c / alpha)' assert_true: 'lch(from lch(.7 45 30 / 40%) l c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) calc(l) calc(c) calc(h))' assert_true: 'lch(from lch(0.7 45 30) calc(l) calc(c) calc(h))' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' assert_true: 'lch(from lch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) none none none)' assert_true: 'lch(from lch(0.7 45 30) none none none)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) none none none / none)' assert_true: 'lch(from lch(0.7 45 30) none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c none)' assert_true: 'lch(from lch(0.7 45 30) l c none)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c none / alpha)' assert_true: 'lch(from lch(0.7 45 30) l c none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30) l c h / none)' assert_true: 'lch(from lch(0.7 45 30) l c h / none)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c none / alpha)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / none)' assert_true: 'lch(from lch(0.7 45 30 / 40%) l c h / none)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(none none none) l c h)' assert_true: 'lch(from lch(none none none) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(none none none / none) l c h / alpha)' assert_true: 'lch(from lch(none none none / none) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 none 30) l c h)' assert_true: 'lch(from lch(0.7 none 30) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(0.7 45 30 / none) l c h / alpha)' assert_true: 'lch(from lch(0.7 45 30 / none) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(2 3 400 / 500%) l c h / alpha)' assert_true: 'oklch(from oklch(2 3 400 / 500%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)' assert_true: 'oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)' assert_true: 'oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from color(display-p3 0 0 0) l c h / alpha)' assert_true: 'oklch(from color(display-p3 0 0 0) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklab(0.7 45 30) l c h / alpha)' assert_true: 'oklch(from oklab(0.7 45 30) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0deg)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l 0 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l 0 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 0 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 25 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / .25)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / .25)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30) l c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30) l c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))' assert_true: 'oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) none none none)' assert_true: 'oklch(from oklch(0.7 0.45 30) none none none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) none none none / none)' assert_true: 'oklch(from oklch(0.7 0.45 30) none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c none)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c none / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30) l c h / none)' assert_true: 'oklch(from oklch(0.7 0.45 30) l c h / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)' assert_true: 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(none none none) l c h)' assert_true: 'oklch(from oklch(none none none) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(none none none / none) l c h / alpha)' assert_true: 'oklch(from oklch(none none none / none) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 none 30) l c h)' assert_true: 'oklch(from oklch(0.7 none 30) l c h)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)' assert_true: 'oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30) alpha c h / l)' assert_true: 'lch(from lch(.7 45 30) alpha c h / l)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30) alpha c h / alpha)' assert_true: 'lch(from lch(.7 45 30) alpha c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30) alpha c c / alpha)' assert_true: 'lch(from lch(.7 45 30) alpha c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c h / l)' assert_true: 'lch(from lch(.7 45 30 / 40%) alpha c h / l)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c h / alpha)' assert_true: 'lch(from lch(.7 45 30 / 40%) alpha c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c c / alpha)' assert_true: 'lch(from lch(.7 45 30 / 40%) alpha c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / l)' assert_true: 'oklch(from oklch(.7 0.45 30) alpha c h / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30) alpha c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30) alpha c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)' assert_true: 'oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(srgb 0.7 0.5 0.3) srgb r g b) srgb r g b)' assert_true: 'color(from color(from color(srgb 0.7 0.5 0.3) srgb r g b) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0 g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r 0 b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g 0 / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0 g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0 b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0 / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0.2 g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 20% g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r 0.2 b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r 20% b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g 0.2 / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g 20% / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0.2)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 20%)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0.2 g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 20% g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0.2 b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 20% b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0.2 / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 20% / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0.2)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 20%)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4 / 5)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4 / 5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4 / -5)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4 / -5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400%)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400% / 500%)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400% / 500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400%)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400% / -500%)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400% / -500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb g b r)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb b alpha r / g)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r r r / r)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb alpha alpha alpha / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb g b r)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb b alpha r / g)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r r r / r)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb alpha alpha alpha / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 1.7 1.5 1.3) srgb r g b)' assert_true: 'color(from color(srgb 1.7 1.5 1.3) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 1.7 1.5 1.3) srgb r g b / alpha)' assert_true: 'color(from color(srgb 1.7 1.5 1.3) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b)' assert_true: 'color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b / alpha)' assert_true: 'color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb -0.7 -0.5 -0.3) srgb r g b)' assert_true: 'color(from color(srgb -0.7 -0.5 -0.3) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb -0.7 -0.5 -0.3) srgb r g b / alpha)' assert_true: 'color(from color(srgb -0.7 -0.5 -0.3) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b)' assert_true: 'color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b / alpha)' assert_true: 'color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb calc(r) calc(g) calc(b))' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb none none none)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb none none none / none)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g none)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g none / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / none)' assert_true: 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g none / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / none)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb none none none) srgb r g b)' assert_true: 'color(from color(srgb none none none) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb none none none / none) srgb r g b / alpha)' assert_true: 'color(from color(srgb none none none / none) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 none 0.3) srgb r g b)' assert_true: 'color(from color(srgb 0.7 none 0.3) srgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb 0.7 0.5 0.3 / none) srgb r g b / alpha)' assert_true: 'color(from color(srgb 0.7 0.5 0.3 / none) srgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b) srgb-linear r g b)' assert_true: 'color(from color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0 / 0)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0 b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0 / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0 g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0 b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0 / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0.2 g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 20% g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0.2 b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 20% b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0.2 / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 20% / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0.2)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 20%)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0.2 g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 20% g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0.2 b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 20% b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0.2 / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 20% / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0.2)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 20%)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4 / 5)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4 / 5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4 / -5)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4 / -5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400%)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400% / 500%)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400% / 500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400%)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400% / -500%)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400% / -500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear g b r)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear b alpha r / g)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r r r / r)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear alpha alpha alpha / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear g b r)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear b alpha r / g)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r r r / r)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear alpha alpha alpha / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear calc(r) calc(g) calc(b))' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none / none)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / none)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g none / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / none)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear none none none) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear none none none) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear none none none / none) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear none none none / none) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 none 0.3) srgb-linear r g b)' assert_true: 'color(from color(srgb-linear 0.7 none 0.3) srgb-linear r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / none) srgb-linear r g b / alpha)' assert_true: 'color(from color(srgb-linear 0.7 0.5 0.3 / none) srgb-linear r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b) a98-rgb r g b)' assert_true: 'color(from color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0 b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0 / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0 g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0 b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0 / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0.2 g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 20% g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0.2 b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 20% b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0.2 / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 20% / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0.2)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 20%)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0.2 g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 20% g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0.2 b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 20% b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0.2 / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 20% / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0.2)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 20%)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4 / 5)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4 / 5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4 / -5)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4 / -5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400%)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400% / 500%)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400% / 500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400%)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400% / -500%)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400% / -500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb g b r)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb b alpha r / g)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r r r / r)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb alpha alpha alpha / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb g b r)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb b alpha r / g)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r r r / r)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb alpha alpha alpha / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb calc(r) calc(g) calc(b))' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none / none)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / none)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g none / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / none)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb none none none) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb none none none) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb none none none / none) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb none none none / none) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 none 0.3) a98-rgb r g b)' assert_true: 'color(from color(a98-rgb 0.7 none 0.3) a98-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / none) a98-rgb r g b / alpha)' assert_true: 'color(from color(a98-rgb 0.7 0.5 0.3 / none) a98-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b) rec2020 r g b)' assert_true: 'color(from color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0 b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0 / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0 g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0 b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0 / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0.2 g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 20% g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0.2 b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 20% b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0.2 / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 20% / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0.2)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 20%)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0.2 g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 20% g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0.2 b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 20% b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0.2 / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 20% / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0.2)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 20%)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4 / 5)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4 / 5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4 / -5)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4 / -5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400%)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400% / 500%)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400% / 500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400%)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400% / -500%)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400% / -500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 g b r)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 b alpha r / g)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r r r / r)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 alpha alpha alpha / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 g b r)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 b alpha r / g)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r r r / r)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 alpha alpha alpha / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b)' assert_true: 'color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b)' assert_true: 'color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b)' assert_true: 'color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b)' assert_true: 'color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 calc(r) calc(g) calc(b))' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none / none)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / none)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g none / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / none)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 none none none) rec2020 r g b)' assert_true: 'color(from color(rec2020 none none none) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 none none none / none) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 none none none / none) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 none 0.3) rec2020 r g b)' assert_true: 'color(from color(rec2020 0.7 none 0.3) rec2020 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(rec2020 0.7 0.5 0.3 / none) rec2020 r g b / alpha)' assert_true: 'color(from color(rec2020 0.7 0.5 0.3 / none) rec2020 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b) prophoto-rgb r g b)' assert_true: 'color(from color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0 b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0 / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0 g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0 b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0 / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0.2 g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 20% g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0.2 b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 20% b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0.2 / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 20% / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0.2)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 20%)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0.2 g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 20% g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0.2 b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 20% b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0.2 / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 20% / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0.2)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 20%)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4 / 5)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4 / 5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4 / -5)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4 / -5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400%)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400% / 500%)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400% / 500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400%)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400% / -500%)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400% / -500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb g b r)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb b alpha r / g)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r r r / r)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb alpha alpha alpha / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb g b r)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb b alpha r / g)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r r r / r)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb alpha alpha alpha / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb calc(r) calc(g) calc(b))' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none / none)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / none)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g none / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / none)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb none none none) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb none none none) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb none none none / none) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb none none none / none) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 none 0.3) prophoto-rgb r g b)' assert_true: 'color(from color(prophoto-rgb 0.7 none 0.3) prophoto-rgb r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / none) prophoto-rgb r g b / alpha)' assert_true: 'color(from color(prophoto-rgb 0.7 0.5 0.3 / none) prophoto-rgb r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b) display-p3 r g b)' assert_true: 'color(from color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0 / 0)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0 b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0 / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0 g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0 b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0 / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0.2 g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 20% g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0.2 b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 20% b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0.2 / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 20% / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0.2)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 20%)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0.2 g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0.2 g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 20% g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 20% g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0.2 b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0.2 b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 20% b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 20% b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0.2 / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 20% / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 20% / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0.2)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 20%)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4 / 5)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4 / 5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4 / -5)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4 / -5)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400%)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400% / 500%)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400% / 500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400%)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400% / -500%)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400% / -500%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 g b r)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 b alpha r / g)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r r r / r)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 alpha alpha alpha / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 g b r)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 g b r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 b alpha r / g)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 b alpha r / g)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r r r / r)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r r r / r)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 alpha alpha alpha / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 alpha alpha alpha / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b)' assert_true: 'color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b)' assert_true: 'color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b)' assert_true: 'color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b)' assert_true: 'color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 calc(r) calc(g) calc(b))' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 calc(r) calc(g) calc(b))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 calc(r) calc(g) calc(b) / calc(alpha))' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 calc(r) calc(g) calc(b) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none / none)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / none)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g none / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / none)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 none none none) display-p3 r g b)' assert_true: 'color(from color(display-p3 none none none) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 none none none / none) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 none none none / none) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 none 0.3) display-p3 r g b)' assert_true: 'color(from color(display-p3 0.7 none 0.3) display-p3 r g b)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(display-p3 0.7 0.5 0.3 / none) display-p3 r g b / alpha)' assert_true: 'color(from color(display-p3 0.7 0.5 0.3 / none) display-p3 r g b / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)' assert_true: 'color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz 0 0 0)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / 0)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y z / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / 20%)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y z / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz y z x)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz y z x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x x x / x)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x x x / x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))' assert_true: 'color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz none none none)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz none none none / none)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y none)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y none / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / none)' assert_true: 'color(from color(xyz 7 -20.5 100) xyz x y z / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y none / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / none)' assert_true: 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz none none none) xyz x y z)' assert_true: 'color(from color(xyz none none none) xyz x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz none none none / none) xyz x y z / alpha)' assert_true: 'color(from color(xyz none none none / none) xyz x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 none 100) xyz x y z)' assert_true: 'color(from color(xyz 7 none 100) xyz x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz 7 -20.5 100 / none) xyz x y z / alpha)' assert_true: 'color(from color(xyz 7 -20.5 100 / none) xyz x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z) xyz-d50 x y z)' assert_true: 'color(from color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z) xyz-d50 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0 / 0)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0 z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0 / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0 y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0 z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0 / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0.2 y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0.2 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0.2 z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0.2 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0.2 / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0.2)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 20%)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0.2 y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0.2 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0.2 z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0.2 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0.2 / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0.2)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 y z x)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 y z x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x x x / x)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x x x / x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 y z x)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 y z x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x x x / x)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x x x / x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 calc(x) calc(y) calc(z))' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 calc(x) calc(y) calc(z))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 calc(x) calc(y) calc(z) / calc(alpha))' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 calc(x) calc(y) calc(z) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none / none)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / none)' assert_true: 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y none / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / none)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 none none none) xyz-d50 x y z)' assert_true: 'color(from color(xyz-d50 none none none) xyz-d50 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 none none none / none) xyz-d50 x y z / alpha)' assert_true: 'color(from color(xyz-d50 none none none / none) xyz-d50 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 none 100) xyz-d50 x y z)' assert_true: 'color(from color(xyz-d50 7 none 100) xyz-d50 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d50 7 -20.5 100 / none) xyz-d50 x y z / alpha)' assert_true: 'color(from color(xyz-d50 7 -20.5 100 / none) xyz-d50 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z) xyz-d65 x y z)' assert_true: 'color(from color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z) xyz-d65 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0 / 0)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0 / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0 z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0 / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0 y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0 z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0 / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0.2 y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0.2 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0.2 z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0.2 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0.2 / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0.2)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 20%)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 20%)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0.2 y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0.2 y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0.2 z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0.2 z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0.2 / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0.2 / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0.2)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0.2)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 y z x)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 y z x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x x x / x)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x x x / x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 y z x)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 y z x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x x x / x)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x x x / x)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 calc(x) calc(y) calc(z))' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 calc(x) calc(y) calc(z))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 calc(x) calc(y) calc(z) / calc(alpha))' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 calc(x) calc(y) calc(z) / calc(alpha))' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none / none)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / none)' assert_true: 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y none / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y none / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / none)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / none)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 none none none) xyz-d65 x y z)' assert_true: 'color(from color(xyz-d65 none none none) xyz-d65 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 none none none / none) xyz-d65 x y z / alpha)' assert_true: 'color(from color(xyz-d65 none none none / none) xyz-d65 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 none 100) xyz-d65 x y z)' assert_true: 'color(from color(xyz-d65 7 none 100) xyz-d65 x y z)' is a supported value for color. expected true got false -FAIL Property color value 'color(from color(xyz-d65 7 -20.5 100 / none) xyz-d65 x y z / alpha)' assert_true: 'color(from color(xyz-d65 7 -20.5 100 / none) xyz-d65 x y z / alpha)' is a supported value for color. expected true got false -FAIL Property color value 'rgb(from var(--bg-color) r g b / 80%)' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 -FAIL Property color value 'lch(from var(--color) calc(l / 2) c h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 23.138971 +/- 1, expected 23.138971 but got 0 -FAIL Property color value 'rgb(from var(--color) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 76 +/- 1, expected 76 but got 0 -FAIL Property color value 'lch(from var(--color) l 0 h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 46.277943 +/- 1, expected 46.277943 but got 0 -FAIL Property color value 'rgb(from indianred 255 g b)' assert_true: 'rgb(from indianred 255 g b)' is a supported value for color. expected true got false +Found 961 tests; 893 PASS, 68 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Property color value 'rgb(from rebeccapurple r g b)' +PASS Property color value 'rgb(from rebeccapurple r g b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)' +PASS Property color value 'rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)' +PASS Property color value 'rgb(from rgb(from rebeccapurple r g b) r g b)' +FAIL Property color value 'rgb(from color(display-p3 0 1 0) r g b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 249 +/- 1, expected 249 but got 255 +FAIL Property color value 'rgb(from lab(100 104.3 -50.9) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 +FAIL Property color value 'rgb(from lab(0 104.3 -50.9) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 +FAIL Property color value 'rgb(from lch(100 116 334) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 +FAIL Property color value 'rgb(from lch(0 116 334) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 +FAIL Property color value 'rgb(from oklab(1 0.365 -0.16) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 92 +FAIL Property color value 'rgb(from oklab(0 0.365 -0.16) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 19 +FAIL Property color value 'rgb(from oklch(1 0.399 336.3) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 91 +FAIL Property color value 'rgb(from oklch(0 0.399 336.3) r g b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 20 +PASS Property color value 'rgb(from rebeccapurple 0 0 0)' +PASS Property color value 'rgb(from rebeccapurple 0 0 0 / 0)' +PASS Property color value 'rgb(from rebeccapurple 0 g b / alpha)' +PASS Property color value 'rgb(from rebeccapurple r 0 b / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g 0 / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g b / 0)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)' +PASS Property color value 'rgb(from rebeccapurple 25 g b / alpha)' +PASS Property color value 'rgb(from rebeccapurple r 25 b / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g 25 / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g b / .25)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)' +PASS Property color value 'rgb(from rebeccapurple 20% g b / alpha)' +PASS Property color value 'rgb(from rebeccapurple r 20% b / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g 20% / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g b / 20%)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)' +PASS Property color value 'rgb(from rebeccapurple 25 g b / 25%)' +PASS Property color value 'rgb(from rebeccapurple r 25 b / 25%)' +PASS Property color value 'rgb(from rebeccapurple r g 25 / 25%)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)' +PASS Property color value 'rgb(from rebeccapurple g b r)' +PASS Property color value 'rgb(from rebeccapurple b alpha r / g)' +PASS Property color value 'rgb(from rebeccapurple r r r / r)' +PASS Property color value 'rgb(from rebeccapurple alpha alpha alpha / alpha)' +FAIL Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) g b r)' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 3 got 4 +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)' +PASS Property color value 'rgb(from rebeccapurple r 20% 10)' +PASS Property color value 'rgb(from rebeccapurple r 10 20%)' +PASS Property color value 'rgb(from rebeccapurple 0% 10 10)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)' +PASS Property color value 'rgb(from rebeccapurple calc(r) calc(g) calc(b))' +PASS Property color value 'rgb(from rebeccapurple r calc(g * 2) 10)' +PASS Property color value 'rgb(from rebeccapurple b calc(r * .5) 10)' +PASS Property color value 'rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)' +PASS Property color value 'rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)' +PASS Property color value 'rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'rgb(from rebeccapurple none none none)' +PASS Property color value 'rgb(from rebeccapurple none none none / none)' +PASS Property color value 'rgb(from rebeccapurple r g none)' +PASS Property color value 'rgb(from rebeccapurple r g none / alpha)' +PASS Property color value 'rgb(from rebeccapurple r g b / none)' +PASS Property color value 'rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)' +PASS Property color value 'rgb(from rgb(20% 40% 60% / 80%) r g b / none)' +PASS Property color value 'rgb(from rgb(none none none) r g b)' +PASS Property color value 'rgb(from rgb(none none none / none) r g b / alpha)' +PASS Property color value 'rgb(from rgb(20% none 60%) r g b)' +PASS Property color value 'rgb(from rgb(20% 40% 60% / none) r g b / alpha)' +PASS Property color value 'hsl(from rebeccapurple h s l)' +PASS Property color value 'hsl(from rebeccapurple h s l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)' +PASS Property color value 'hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)' +PASS Property color value 'hsl(from hsl(from rebeccapurple h s l) h s l)' +FAIL Property color value 'hsl(from color(display-p3 0 1 0) h s l / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 249 +/- 1, expected 249 but got 255 +FAIL Property color value 'hsl(from lab(100 104.3 -50.9) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 +FAIL Property color value 'hsl(from lab(0 104.3 -50.9) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 +FAIL Property color value 'hsl(from lch(100 116 334) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 +FAIL Property color value 'hsl(from lch(0 116 334) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 +FAIL Property color value 'hsl(from oklab(1 0.365 -0.16) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 92 +FAIL Property color value 'hsl(from oklab(0 0.365 -0.16) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 19 +FAIL Property color value 'hsl(from oklch(1 0.399 336.3) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 91 +FAIL Property color value 'hsl(from oklch(0 0.399 336.3) h s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 20 +PASS Property color value 'hsl(from rebeccapurple 0 0% 0%)' +PASS Property color value 'hsl(from rebeccapurple 0deg 0% 0%)' +PASS Property color value 'hsl(from rebeccapurple 0 0% 0% / 0)' +PASS Property color value 'hsl(from rebeccapurple 0deg 0% 0% / 0)' +PASS Property color value 'hsl(from rebeccapurple 0 s l / alpha)' +PASS Property color value 'hsl(from rebeccapurple 0deg s l / alpha)' +PASS Property color value 'hsl(from rebeccapurple h 0% l / alpha)' +PASS Property color value 'hsl(from rebeccapurple h s 0% / alpha)' +PASS Property color value 'hsl(from rebeccapurple h s l / 0)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)' +PASS Property color value 'hsl(from rebeccapurple 25 s l / alpha)' +PASS Property color value 'hsl(from rebeccapurple 25deg s l / alpha)' +PASS Property color value 'hsl(from rebeccapurple h 20% l / alpha)' +PASS Property color value 'hsl(from rebeccapurple h s 20% / alpha)' +PASS Property color value 'hsl(from rebeccapurple h s l / .25)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)' +PASS Property color value 'hsl(from rebeccapurple h l s)' +PASS Property color value 'hsl(from rebeccapurple h alpha l / s)' +PASS Property color value 'hsl(from rebeccapurple h l l / l)' +PASS Property color value 'hsl(from rebeccapurple h alpha alpha / alpha)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h l s)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' +PASS Property color value 'hsl(from rebeccapurple calc(h) calc(s) calc(l))' +PASS Property color value 'hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))' +PASS Property color value 'hsl(from rebeccapurple none none none)' +PASS Property color value 'hsl(from rebeccapurple none none none / none)' +PASS Property color value 'hsl(from rebeccapurple h s none)' +PASS Property color value 'hsl(from rebeccapurple h s none / alpha)' +PASS Property color value 'hsl(from rebeccapurple h s l / none)' +PASS Property color value 'hsl(from rebeccapurple none s l / alpha)' +PASS Property color value 'hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)' +PASS Property color value 'hsl(from hsl(120deg 20% 50% / .5) h s l / none)' +PASS Property color value 'hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)' +PASS Property color value 'hsl(from hsl(none none none) h s l)' +PASS Property color value 'hsl(from hsl(none none none / none) h s l / alpha)' +PASS Property color value 'hsl(from hsl(120deg none 50% / .5) h s l)' +PASS Property color value 'hsl(from hsl(120deg 20% 50% / none) h s l / alpha)' +PASS Property color value 'hsl(from hsl(none 20% 50% / .5) h s l / alpha)' +PASS Property color value 'hwb(from rebeccapurple h w b)' +PASS Property color value 'hwb(from rebeccapurple h w b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)' +PASS Property color value 'hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)' +PASS Property color value 'hwb(from hwb(from rebeccapurple h w b) h w b)' +FAIL Property color value 'hwb(from color(display-p3 0 1 0) h w b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 249 +/- 1, expected 249 but got 255 +FAIL Property color value 'hwb(from lab(100 104.3 -50.9) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 +FAIL Property color value 'hwb(from lab(0 104.3 -50.9) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 +FAIL Property color value 'hwb(from lch(100 116 334) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 150 +FAIL Property color value 'hwb(from lch(0 116 334) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 42 +/- 1, expected 42 but got 90 +FAIL Property color value 'hwb(from oklab(1 0.365 -0.16) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 92 +FAIL Property color value 'hwb(from oklab(0 0.365 -0.16) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 19 +FAIL Property color value 'hwb(from oklch(1 0.399 336.3) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 1, expected 255 +/- 1, expected 255 but got 91 +FAIL Property color value 'hwb(from oklch(0 0.399 336.3) h w b)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0 +/- 1, expected 0 but got 20 +PASS Property color value 'hwb(from rebeccapurple 0 0% 0%)' +PASS Property color value 'hwb(from rebeccapurple 0deg 0% 0%)' +PASS Property color value 'hwb(from rebeccapurple 0 0% 0% / 0)' +PASS Property color value 'hwb(from rebeccapurple 0deg 0% 0% / 0)' +PASS Property color value 'hwb(from rebeccapurple 0 w b / alpha)' +PASS Property color value 'hwb(from rebeccapurple 0deg w b / alpha)' +PASS Property color value 'hwb(from rebeccapurple h 0% b / alpha)' +PASS Property color value 'hwb(from rebeccapurple h w 0% / alpha)' +PASS Property color value 'hwb(from rebeccapurple h w b / 0)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)' +PASS Property color value 'hwb(from rebeccapurple 25 w b / alpha)' +PASS Property color value 'hwb(from rebeccapurple 25deg w b / alpha)' +PASS Property color value 'hwb(from rebeccapurple h 20% b / alpha)' +PASS Property color value 'hwb(from rebeccapurple h w 20% / alpha)' +PASS Property color value 'hwb(from rebeccapurple h w b / .2)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)' +PASS Property color value 'hwb(from rebeccapurple h b w)' +PASS Property color value 'hwb(from rebeccapurple h alpha w / b)' +PASS Property color value 'hwb(from rebeccapurple h w w / w)' +PASS Property color value 'hwb(from rebeccapurple h alpha alpha / alpha)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h b w)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)' +PASS Property color value 'hwb(from rebeccapurple calc(h) calc(w) calc(b))' +PASS Property color value 'hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))' +PASS Property color value 'hwb(from rebeccapurple none none none)' +PASS Property color value 'hwb(from rebeccapurple none none none / none)' +PASS Property color value 'hwb(from rebeccapurple h w none)' +PASS Property color value 'hwb(from rebeccapurple h w none / alpha)' +PASS Property color value 'hwb(from rebeccapurple h w b / none)' +PASS Property color value 'hwb(from rebeccapurple none w b / alpha)' +PASS Property color value 'hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)' +PASS Property color value 'hwb(from hwb(120deg 20% 50% / .5) h w b / none)' +PASS Property color value 'hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)' +PASS Property color value 'hwb(from hwb(none none none) h w b)' +PASS Property color value 'hwb(from hwb(none none none / none) h w b / alpha)' +PASS Property color value 'hwb(from hwb(120deg none 50% / .5) h w b)' +PASS Property color value 'hwb(from hwb(120deg 20% 50% / none) h w b / alpha)' +PASS Property color value 'hwb(from hwb(none 20% 50% / .5) h w b / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l a b)' +PASS Property color value 'lab(from lab(25 20 50) l a b / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a b / alpha)' +FAIL Property color value 'lab(from lab(200 300 400 / 500%) l a b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 200 +/- 0.0001, expected 200 but got 100 +PASS Property color value 'lab(from lab(-200 -300 -400 / -500%) l a b / alpha)' +PASS Property color value 'lab(from lab(from lab(25 20 50) l a b) l a b)' +PASS Property color value 'lab(from color(display-p3 0 0 0) l a b / alpha)' +PASS Property color value 'lab(from lab(25 20 50) 0 0 0)' +PASS Property color value 'lab(from lab(25 20 50) 0 0 0 / 0)' +PASS Property color value 'lab(from lab(25 20 50) 0 a b / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l 0 b / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l a 0 / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l a b / 0)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) 0 a b / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l 0 b / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a 0 / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a b / 0)' +PASS Property color value 'lab(from lab(25 20 50) 35 a b / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l 35 b / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l a 35 / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l a b / .35)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) 35 a b / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l 35 b / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a 35 / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a b / .35)' +FAIL Property color value 'lab(from lab(0.7 45 30 / 40%) 200 300 400 / 500)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 200 +/- 0.0001, expected 200 but got 100 +PASS Property color value 'lab(from lab(0.7 45 30 / 40%) -200 -300 -400 / -500)' +PASS Property color value 'lab(from lab(25 20 50) l b a)' +PASS Property color value 'lab(from lab(25 20 50) l a a / a)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l b a)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a a / a)' +PASS Property color value 'lab(from lab(25 20 50) calc(l) calc(a) calc(b))' +PASS Property color value 'lab(from lab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' +PASS Property color value 'lab(from lab(25 20 50) none none none)' +PASS Property color value 'lab(from lab(25 20 50) none none none / none)' +PASS Property color value 'lab(from lab(25 20 50) l a none)' +PASS Property color value 'lab(from lab(25 20 50) l a none / alpha)' +PASS Property color value 'lab(from lab(25 20 50) l a b / none)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a none / alpha)' +PASS Property color value 'lab(from lab(25 20 50 / 40%) l a b / none)' +PASS Property color value 'lab(from lab(none none none) l a b)' +PASS Property color value 'lab(from lab(none none none / none) l a b / alpha)' +PASS Property color value 'lab(from lab(25 none 50) l a b)' +PASS Property color value 'lab(from lab(25 20 50 / none) l a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)' +PASS Property color value 'oklab(from oklab(2 3 4 / 500%) l a b / alpha)' +PASS Property color value 'oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)' +PASS Property color value 'oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)' +PASS Property color value 'oklab(from color(display-p3 0 0 0) l a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / 0)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / .35)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)' +PASS Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)' +PASS Property color value 'oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l b a)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a a / a)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) none none none / none)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a none / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5) l a b / none)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)' +PASS Property color value 'oklab(from oklab(none none none) l a b)' +PASS Property color value 'oklab(from oklab(none none none / none) l a b / alpha)' +PASS Property color value 'oklab(from oklab(0.25 none 0.5) l a b)' +PASS Property color value 'oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)' +FAIL Property color value 'lab(from lab(.7 45 30) alpha b a / l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 1 +FAIL Property color value 'lab(from lab(.7 45 30) alpha a b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 1 +FAIL Property color value 'lab(from lab(.7 45 30) alpha a a / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 1 +FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha b a / l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 40 +/- 0.0001, expected 40 but got 0.4 +FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha a b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 40 +/- 0.0001, expected 40 but got 0.4 +FAIL Property color value 'lab(from lab(.7 45 30 / 40%) alpha a a / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 40 +/- 0.0001, expected 40 but got 0.4 +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha b a / l)' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 0.01 +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 0.01 +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.4 +/- 0.0001, expected 0.4 but got 0.004 +FAIL Property color value 'oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.4 +/- 0.0001, expected 0.4 but got 0.004 +PASS Property color value 'lch(from lch(0.7 45 30) l c h)' +PASS Property color value 'lch(from lch(0.7 45 30) l c h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / alpha)' +FAIL Property color value 'lch(from lch(200 300 400 / 500%) l c h / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 200 +/- 0.0001, expected 200 but got 100 +PASS Property color value 'lch(from lch(-200 -300 -400 / -500%) l c h / alpha)' +PASS Property color value 'lch(from lch(from lch(0.7 45 30) l c h) l c h)' +PASS Property color value 'lch(from color(display-p3 0 0 0) l c h / alpha)' +PASS Property color value 'lch(from lab(0.7 45 30) l c h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) 0 0 0)' +PASS Property color value 'lch(from lch(0.7 45 30) 0 0 0deg)' +PASS Property color value 'lch(from lch(0.7 45 30) 0 0 0 / 0)' +PASS Property color value 'lch(from lch(0.7 45 30) 0 0 0deg / 0)' +PASS Property color value 'lch(from lch(0.7 45 30) 0 c h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l 0 h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c 0 / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c 0deg / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c h / 0)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) 0 c h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l 0 h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c 0 / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c 0deg / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / 0)' +PASS Property color value 'lch(from lch(0.7 45 30) 25 c h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l 25 h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c 25 / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c 25deg / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c h / .25)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) 25 c h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l 25 h / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c 25 / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c 25deg / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / .25)' +FAIL Property color value 'lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 200 +/- 0.0001, expected 200 but got 100 +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) -200 -300 -400 / -500)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) 50 120 400deg / 500)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) 50 120 -400deg / -500)' +PASS Property color value 'lch(from lch(.7 45 30) l c c / alpha)' +PASS Property color value 'lch(from lch(.7 45 30 / 40%) l c c / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) calc(l) calc(c) calc(h))' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' +PASS Property color value 'lch(from lch(0.7 45 30) none none none)' +PASS Property color value 'lch(from lch(0.7 45 30) none none none / none)' +PASS Property color value 'lch(from lch(0.7 45 30) l c none)' +PASS Property color value 'lch(from lch(0.7 45 30) l c none / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30) l c h / none)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c none / alpha)' +PASS Property color value 'lch(from lch(0.7 45 30 / 40%) l c h / none)' +PASS Property color value 'lch(from lch(none none none) l c h)' +PASS Property color value 'lch(from lch(none none none / none) l c h / alpha)' +PASS Property color value 'lch(from lch(0.7 none 30) l c h)' +PASS Property color value 'lch(from lch(0.7 45 30 / none) l c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c h)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)' +PASS Property color value 'oklch(from oklch(2 3 400 / 500%) l c h / alpha)' +PASS Property color value 'oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)' +PASS Property color value 'oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)' +PASS Property color value 'oklch(from color(display-p3 0 0 0) l c h / alpha)' +PASS Property color value 'oklch(from oklab(0.7 45 30) l c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) 0 c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l 0 h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c 0 / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c h / 0)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c 25 / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c h / .25)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25 / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)' +PASS Property color value 'oklch(from oklch(.7 0.45 30) l c c / alpha)' +PASS Property color value 'oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) none none none)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) none none none / none)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c none)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c none / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30) l c h / none)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)' +PASS Property color value 'oklch(from oklch(none none none) l c h)' +PASS Property color value 'oklch(from oklch(none none none / none) l c h / alpha)' +PASS Property color value 'oklch(from oklch(0.7 none 30) l c h)' +PASS Property color value 'oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)' +FAIL Property color value 'lch(from lch(.7 45 30) alpha c h / l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 1 +FAIL Property color value 'lch(from lch(.7 45 30) alpha c h / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 1 +FAIL Property color value 'lch(from lch(.7 45 30) alpha c c / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 100 +/- 0.0001, expected 100 but got 1 +FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c h / l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 40 +/- 0.0001, expected 40 but got 0.4 +FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c h / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 40 +/- 0.0001, expected 40 but got 0.4 +FAIL Property color value 'lch(from lch(.7 45 30 / 40%) alpha c c / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 40 +/- 0.0001, expected 40 but got 0.4 +FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / l)' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 +FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c h / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 0.01 +FAIL Property color value 'oklch(from oklch(.7 0.45 30) alpha c c / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 1 +/- 0.0001, expected 1 but got 0.01 +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.4 +/- 0.0001, expected 0.4 but got 0.004 +FAIL Property color value 'oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 0.4 +/- 0.0001, expected 0.4 but got 0.004 +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / alpha)' +PASS Property color value 'color(from color(from color(srgb 0.7 0.5 0.3) srgb r g b) srgb r g b)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0 g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r 0 b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g 0 / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0 g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0 b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0 / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 0.2 g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 20% g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r 0.2 b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r 20% b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g 0.2 / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g 20% / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0.2)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / 20%)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0.2 g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 20% g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0.2 b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 20% b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0.2 / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 20% / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0.2)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 20%)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4 / 5)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4 / -5)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400%)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400% / 500%)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400%)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400% / -500%)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb g b r)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb b alpha r / g)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r r r / r)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb g b r)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb b alpha r / g)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r r r / r)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(srgb 1.7 1.5 1.3) srgb r g b)' +PASS Property color value 'color(from color(srgb 1.7 1.5 1.3) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b)' +PASS Property color value 'color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb -0.7 -0.5 -0.3) srgb r g b)' +PASS Property color value 'color(from color(srgb -0.7 -0.5 -0.3) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b)' +PASS Property color value 'color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb calc(r) calc(g) calc(b))' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb none none none)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb none none none / none)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g none)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g none / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3) srgb r g b / none)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g none / alpha)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / none)' +PASS Property color value 'color(from color(srgb none none none) srgb r g b)' +PASS Property color value 'color(from color(srgb none none none / none) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb 0.7 none 0.3) srgb r g b)' +PASS Property color value 'color(from color(srgb 0.7 0.5 0.3 / none) srgb r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0 / 0)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0 b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0 / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0 g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0 b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0 / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0.2 g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 20% g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0.2 b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 20% b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0.2 / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 20% / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0.2)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 20%)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0.2 g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 20% g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0.2 b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 20% b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0.2 / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 20% / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0.2)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 20%)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4 / 5)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4 / -5)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400%)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400% / 500%)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400%)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400% / -500%)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear g b r)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear b alpha r / g)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r r r / r)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear g b r)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear b alpha r / g)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r r r / r)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear calc(r) calc(g) calc(b))' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none / none)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / none)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g none / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / none)' +PASS Property color value 'color(from color(srgb-linear none none none) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear none none none / none) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(srgb-linear 0.7 none 0.3) srgb-linear r g b)' +PASS Property color value 'color(from color(srgb-linear 0.7 0.5 0.3 / none) srgb-linear r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0 b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0 / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0 g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0 b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0 / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0.2 g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 20% g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0.2 b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 20% b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0.2 / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 20% / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0.2)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 20%)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0.2 g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 20% g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0.2 b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 20% b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0.2 / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 20% / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0.2)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 20%)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4 / 5)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4 / -5)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400%)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400% / 500%)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400%)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400% / -500%)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb g b r)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb b alpha r / g)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r r r / r)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb g b r)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb b alpha r / g)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r r r / r)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb calc(r) calc(g) calc(b))' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none / none)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / none)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g none / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / none)' +PASS Property color value 'color(from color(a98-rgb none none none) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb none none none / none) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(a98-rgb 0.7 none 0.3) a98-rgb r g b)' +PASS Property color value 'color(from color(a98-rgb 0.7 0.5 0.3 / none) a98-rgb r g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0 g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0 b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0 / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0 g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0 b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0 / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 0.2 g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 20% g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0.2 b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r 20% b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0.2 / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 20% / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0.2)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 20%)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0.2 g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 20% g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0.2 b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 20% b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0.2 / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 20% / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0.2)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 20%)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4 / 5)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4 / -5)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400%)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400% / 500%)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400%)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400% / -500%)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 g b r)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 b alpha r / g)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r r r / r)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 g b r)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 b alpha r / g)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r r r / r)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 calc(r) calc(g) calc(b))' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none / none)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / none)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g none / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / none)' +PASS Property color value 'color(from color(rec2020 none none none) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 none none none / none) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(rec2020 0.7 none 0.3) rec2020 r g b)' +PASS Property color value 'color(from color(rec2020 0.7 0.5 0.3 / none) rec2020 r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0 b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0 / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0 g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0 b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0 / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0.2 g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 20% g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0.2 b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 20% b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0.2 / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 20% / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0.2)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 20%)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0.2 g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 20% g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0.2 b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 20% b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0.2 / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 20% / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0.2)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 20%)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4 / 5)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4 / -5)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400%)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400% / 500%)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400%)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400% / -500%)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb g b r)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb b alpha r / g)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r r r / r)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb g b r)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb b alpha r / g)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r r r / r)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb calc(r) calc(g) calc(b))' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none / none)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / none)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g none / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / none)' +PASS Property color value 'color(from color(prophoto-rgb none none none) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb none none none / none) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 none 0.3) prophoto-rgb r g b)' +PASS Property color value 'color(from color(prophoto-rgb 0.7 0.5 0.3 / none) prophoto-rgb r g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0 / 0)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0 g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0 b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0 / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0 g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0 b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0 / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 0.2 g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 20% g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0.2 b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r 20% b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0.2 / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 20% / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0.2)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 20%)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0.2 g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 20% g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0.2 b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 20% b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0.2 / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 20% / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0.2)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 20%)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4 / 5)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4 / -5)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400%)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400% / 500%)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400%)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400% / -500%)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 g b r)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 b alpha r / g)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r r r / r)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 g b r)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 b alpha r / g)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r r r / r)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 alpha alpha alpha / alpha)' +PASS Property color value 'color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 calc(r) calc(g) calc(b))' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 calc(r) calc(g) calc(b) / calc(alpha))' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none / none)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / none)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g none / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / none)' +PASS Property color value 'color(from color(display-p3 none none none) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 none none none / none) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(display-p3 0.7 none 0.3) display-p3 r g b)' +PASS Property color value 'color(from color(display-p3 0.7 0.5 0.3 / none) display-p3 r g b / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)' +PASS Property color value 'color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz 0 0 0)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / 0)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / 20%)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz y z x)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x x x / x)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz none none none)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz none none none / none)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y none)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y none / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100) xyz x y z / none)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y none / alpha)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / none)' +PASS Property color value 'color(from color(xyz none none none) xyz x y z)' +PASS Property color value 'color(from color(xyz none none none / none) xyz x y z / alpha)' +PASS Property color value 'color(from color(xyz 7 none 100) xyz x y z)' +PASS Property color value 'color(from color(xyz 7 -20.5 100 / none) xyz x y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / alpha)' +PASS Property color value 'color(from color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z) xyz-d50 x y z)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0 / 0)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0 z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0 / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0 y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0 z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0 / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 0.2 y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0.2 z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0.2 / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0.2)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 20%)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0.2 y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0.2 z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0.2 / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0.2)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 y z x)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x x x / x)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 y z x)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x x x / x)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 calc(x) calc(y) calc(z))' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 calc(x) calc(y) calc(z) / calc(alpha))' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none / none)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / none)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y none / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / none)' +PASS Property color value 'color(from color(xyz-d50 none none none) xyz-d50 x y z)' +PASS Property color value 'color(from color(xyz-d50 none none none / none) xyz-d50 x y z / alpha)' +PASS Property color value 'color(from color(xyz-d50 7 none 100) xyz-d50 x y z)' +PASS Property color value 'color(from color(xyz-d50 7 -20.5 100 / none) xyz-d50 x y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / alpha)' +PASS Property color value 'color(from color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z) xyz-d65 x y z)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0 / 0)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0 z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0 / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0 y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0 z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0 / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 0.2 y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0.2 z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0.2 / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0.2)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 20%)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0.2 y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0.2 z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0.2 / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0.2)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 y z x)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x x x / x)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 y z x)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x x x / x)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 calc(x) calc(y) calc(z))' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 calc(x) calc(y) calc(z) / calc(alpha))' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none / none)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / none)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y none / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / none)' +PASS Property color value 'color(from color(xyz-d65 none none none) xyz-d65 x y z)' +PASS Property color value 'color(from color(xyz-d65 none none none / none) xyz-d65 x y z / alpha)' +PASS Property color value 'color(from color(xyz-d65 7 none 100) xyz-d65 x y z)' +PASS Property color value 'color(from color(xyz-d65 7 -20.5 100 / none) xyz-d65 x y z / alpha)' +PASS Property color value 'rgb(from var(--bg-color) r g b / 80%)' +FAIL Property color value 'lch(from var(--color) calc(l / 2) c h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 23.138971 +/- 0.0001, expected 23.138971 but got 23.1363 +PASS Property color value 'rgb(from var(--color) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11))' +FAIL Property color value 'lch(from var(--color) l 0 h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 46.277943 +/- 0.0001, expected 46.277943 but got 46.2725 +PASS Property color value 'rgb(from indianred 255 g b)' FAIL Property color value 'hsl(from var(--accent) calc(h + 180deg) s l)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 178 +/- 1, expected 178 but got 0 -FAIL Property color value 'lab(from var(--mycolor) l a b / 100%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 1, expected 62.751923 but got 0 -FAIL Property color value 'lab(from var(--mycolor) l a b / calc(alpha * 0.8))' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 +FAIL Property color value 'lab(from var(--mycolor) l a b / 100%)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 0.0001, expected 62.751923 but got 62.746 +FAIL Property color value 'lab(from var(--mycolor) l a b / calc(alpha * 0.8))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 0.0001, expected 62.751923 but got 62.746 FAIL Property color value 'lab(from var(--mycolor) l a b / calc(alpha - 20%))' assert_array_approx_equals: Numeric parameters are approximately equal. lengths differ, expected 4 got 3 -FAIL Property color value 'lab(from var(--mycolor) l 0 0)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 1, expected 62.751923 but got 0 -FAIL Property color value 'lch(from peru calc(l * 0.8) c h)' assert_true: 'lch(from peru calc(l * 0.8) c h)' is a supported value for color. expected true got false +FAIL Property color value 'lab(from var(--mycolor) l 0 0)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 0.0001, expected 62.751923 but got 62.746 +FAIL Property color value 'lch(from peru calc(l * 0.8) c h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 49.80138 +/- 0.0001, expected 49.80138 but got 49.7972 FAIL Property color value 'LCH(from var(--accent) l c calc(h + 180deg))' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 65.49473 +/- 1, expected 65.49473 but got 0 -FAIL Property color value 'lch(from var(--mycolor) l 0 h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 1, expected 62.751923 but got 0 -FAIL Property color value 'var(--mygray)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 1, expected 62.751923 but got 0 -FAIL Property color value 'lch(from var(--mygray) l 30 h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 1, expected 62.751923 but got 0 +FAIL Property color value 'lch(from var(--mycolor) l 0 h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 0.0001, expected 62.751923 but got 62.746 +FAIL Property color value 'var(--mygray)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 0.0001, expected 62.751923 but got 62.746 +FAIL Property color value 'lch(from var(--mygray) l 30 h)' assert_array_approx_equals: Numeric parameters are approximately equal. property 0, expected 62.751923 +/- 0.0001, expected 62.751923 but got 62.746 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color-expected.txt new file mode 100644 index 0000000..a518847 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-invalid-relative-color-expected.txt
@@ -0,0 +1,158 @@ +This is a testharness.js-based test. +Found 154 tests; 130 PASS, 24 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS e.style['color'] = "rgb(from rebeccapurple r 10deg 10)" should not set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 10 10deg)" should not set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 10deg g b)" should not set the property value +PASS e.style['color'] = "rgb(from rgb(10%, 20%, 30%, 40%) r 10deg 10)" should not set the property value +PASS e.style['color'] = "rgb(from rgb(10%, 20%, 30%, 40%) r 10 10deg)" should not set the property value +PASS e.style['color'] = "rgb(from rgb(10%, 20%, 30%, 40%) 10deg g b)" should not set the property value +PASS e.style['color'] = "rgb(from rebeccapurple red g b)" should not set the property value +PASS e.style['color'] = "rgb(from rebeccapurple l g b)" should not set the property value +PASS e.style['color'] = "rgb(from rebeccapurple h g b)" should not set the property value +PASS e.style['color'] = "rgba(from rebeccapurple r g b)" should not set the property value +PASS e.style['color'] = "rgba(from rgb(10%, 20%, 30%, 40%) r g b / alpha)" should not set the property value +FAIL e.style['color'] = "hsl(from rebeccapurple s h l)" should not set the property value assert_equals: expected "" but got "rgb(255, 0, 0)" +FAIL e.style['color'] = "hsl(from rebeccapurple s s s / s)" should not set the property value assert_equals: expected "" but got "rgba(191, 65, 64, 0.5)" +FAIL e.style['color'] = "hsl(from rebeccapurple h h h / h)" should not set the property value assert_equals: expected "" but got "rgb(255, 255, 0)" +FAIL e.style['color'] = "hsl(from rebeccapurple alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "rgb(255, 255, 255)" +FAIL e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) s h l)" should not set the property value assert_equals: expected "" but got "rgba(255, 0, 0, 0.4)" +FAIL e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) s s s / s)" should not set the property value assert_equals: expected "" but got "rgba(191, 65, 64, 0.5)" +FAIL e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) h h h / h)" should not set the property value assert_equals: expected "" but got "rgb(255, 255, 0)" +FAIL e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "rgba(143, 62, 61, 0.4)" +PASS e.style['color'] = "hsl(from rebeccapurple h 10% 10)" should not set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h 10 10%)" should not set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 10% s l)" should not set the property value +PASS e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) h 10% 10)" should not set the property value +PASS e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) h 10 10%)" should not set the property value +PASS e.style['color'] = "hsl(from rgb(10%, 20%, 30%, 40%) 10% s l)" should not set the property value +PASS e.style['color'] = "hsl(from rebeccapurple hue s l)" should not set the property value +PASS e.style['color'] = "hsl(from rebeccapurple x s l)" should not set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h g b)" should not set the property value +PASS e.style['color'] = "hsla(from rebeccapurple h s l)" should not set the property value +PASS e.style['color'] = "hsla(from rgb(10%, 20%, 30%, 40%) h s l / alpha)" should not set the property value +FAIL e.style['color'] = "hwb(from rebeccapurple w h b)" should not set the property value assert_equals: expected "" but got "rgb(255, 255, 255)" +FAIL e.style['color'] = "hwb(from rebeccapurple b b b / b)" should not set the property value assert_equals: expected "" but got "rgba(153, 102, 102, 0.4)" +FAIL e.style['color'] = "hwb(from rebeccapurple h h h / h)" should not set the property value assert_equals: expected "" but got "rgb(128, 128, 128)" +FAIL e.style['color'] = "hwb(from rebeccapurple alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "rgb(128, 128, 128)" +FAIL e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) w b h)" should not set the property value assert_equals: expected "" but got "rgba(1, 1, 1, 0.4)" +FAIL e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) b b b / b)" should not set the property value assert_equals: expected "" but got "rgba(128, 128, 128, 0.7)" +FAIL e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) h h h / h)" should not set the property value assert_equals: expected "" but got "rgb(128, 128, 128)" +FAIL e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "rgba(153, 102, 102, 0.4)" +PASS e.style['color'] = "hwb(from rebeccapurple h 10% 10)" should not set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h 10 10%)" should not set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 10% w b)" should not set the property value +PASS e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) h 10% 10)" should not set the property value +PASS e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) h 10 10%)" should not set the property value +PASS e.style['color'] = "hwb(from rgb(10%, 20%, 30%, 40%) 10% w b)" should not set the property value +PASS e.style['color'] = "hwb(from rebeccapurple hue w b)" should not set the property value +PASS e.style['color'] = "hwb(from rebeccapurple x w b)" should not set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h g b)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50) l 10deg 10)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50) l 10 10deg)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50) 10deg a b)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50 / 40%) l 10deg 10)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50 / 40%) l 10 10deg)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50 / 40%) 10deg a b)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50) lightness a b)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50) x a b)" should not set the property value +PASS e.style['color'] = "lab(from lab(.25 20 50) h g b)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50) l 10deg 10)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50) l 10 10deg)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50) 10deg a b)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50 / 40%) l 10deg 10)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50 / 40%) l 10 10deg)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50 / 40%) 10deg a b)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50) lightness a b)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50) x a b)" should not set the property value +PASS e.style['color'] = "oklab(from oklab(.25 20 50) h g b)" should not set the property value +FAIL e.style['color'] = "lch(from lch(.70 45 30) h l c / alpha)" should not set the property value assert_equals: expected "" but got "lch(30 0.7 45)" +FAIL e.style['color'] = "lch(from lch(.70 45 30) alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "lch(1 1 1)" +FAIL e.style['color'] = "lch(from lch(.70 45 30 / 40%) h l c / alpha)" should not set the property value assert_equals: expected "" but got "lch(30 0.7 45 / 0.4)" +FAIL e.style['color'] = "lch(from lch(.70 45 30 / 40%) alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "lch(0.4 0.4 0.4 / 0.4)" +PASS e.style['color'] = "lch(from lch(.70 45 30) l 10deg h)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30) l c 10%)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30) 10deg c h)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30 / 40%) l 10deg h)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30 / 40%) l c 10%)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30 / 40%) 10deg c h)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30) lightness c h)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30) x c h)" should not set the property value +PASS e.style['color'] = "lch(from lch(.70 45 30) l g b)" should not set the property value +FAIL e.style['color'] = "oklch(from oklch(.70 45 30) h l c / alpha)" should not set the property value assert_equals: expected "" but got "oklch(0.3 70 45)" +FAIL e.style['color'] = "oklch(from oklch(.70 45 30) alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "oklch(0.01 1 1)" +FAIL e.style['color'] = "oklch(from oklch(.70 45 30 / 40%) h l c / alpha)" should not set the property value assert_equals: expected "" but got "oklch(0.3 70 45 / 0.4)" +FAIL e.style['color'] = "oklch(from oklch(.70 45 30 / 40%) alpha alpha alpha / alpha)" should not set the property value assert_equals: expected "" but got "oklch(0.004 0.4 0.4 / 0.4)" +PASS e.style['color'] = "oklch(from oklch(.70 45 30) l 10deg h)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30) l c 10%)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30) 10deg c h)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30 / 40%) l 10deg h)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30 / 40%) l c 10%)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30 / 40%) 10deg c h)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30) lightness c h)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30) x c h)" should not set the property value +PASS e.style['color'] = "oklch(from oklch(.70 45 30) l g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 10deg g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 10deg b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb red g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb x g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb l g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 10deg g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 10deg b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear red g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear x g b)" should not set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear l g b)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 10deg g b)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 10deg b)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb red g b)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb x g b)" should not set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb l g b)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 10deg g b)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 10deg b)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 red g b)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 x g b)" should not set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 l g b)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 10deg g b)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 10deg b)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb red g b)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb x g b)" should not set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb l g b)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 10deg g b)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 10deg b)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 red g b)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 x g b)" should not set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 l g b)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 10deg y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x 10deg z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz red y)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz r y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz l y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 10deg y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 10deg z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 red y)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 r y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 l y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 10deg y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 10deg z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 10deg)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 red y)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 r y z)" should not set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 l y z)" should not set the property value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt index ff73eaa..0e9c4e7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-color/parsing/color-valid-relative-color-expected.txt
@@ -1,962 +1,962 @@ This is a testharness.js-based test. -Found 961 tests; 13 PASS, 948 FAIL, 0 TIMEOUT, 0 NOTRUN. -FAIL e.style['color'] = "rgb(from rebeccapurple r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(from rebeccapurple r g b) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from color(display-p3 0 1 0) r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from lab(100 104.3 -50.9) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from lab(0 104.3 -50.9) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from lch(100 116 334) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from lch(0 116 334) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from oklab(1 0.365 -0.16) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from oklab(0 0.365 -0.16) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from oklch(1 0.399 336.3) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from oklch(0 0.399 336.3) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 25 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r 25 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g 25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g b / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 25 g b / 25%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r 25 b / 25%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g 25 / 25%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r 20% 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r 10 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple 0% 10 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r calc(g * 2) 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple b calc(r * .5) 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rebeccapurple r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20% 40% 60% / 80%) r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(none none none) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(none none none / none) r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20% none 60%) r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "rgb(from rgb(20% 40% 60% / none) r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(from rebeccapurple h s l) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from color(display-p3 0 1 0) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from lab(100 104.3 -50.9) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from lab(0 104.3 -50.9) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from lch(100 116 334) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from lch(0 116 334) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from oklab(1 0.365 -0.16) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from oklab(0 0.365 -0.16) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from oklch(1 0.399 336.3) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from oklch(0 0.399 336.3) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 0 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 0deg 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 0 0% 0% / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 0deg 0% 0% / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 0 s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 0deg s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h 0% l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s 0% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s l / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 25 s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple 25deg s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h 20% l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s l / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h l s)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h alpha l / s)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h l l / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h l s)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple calc(h) calc(s) calc(l))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple h s l / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from rebeccapurple none s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s l / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(none none none) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(none none none / none) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(120deg none 50% / .5) h s l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(120deg 20% 50% / none) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hsl(from hsl(none 20% 50% / .5) h s l / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(from rebeccapurple h w b) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from color(display-p3 0 1 0) h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from lab(100 104.3 -50.9) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from lab(0 104.3 -50.9) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from lch(100 116 334) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from lch(0 116 334) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from oklab(1 0.365 -0.16) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from oklab(0 0.365 -0.16) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from oklch(1 0.399 336.3) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from oklch(0 0.399 336.3) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 0 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 0deg 0% 0%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 0 0% 0% / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 0deg 0% 0% / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 0 w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 0deg w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h 0% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w 0% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 25 w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple 25deg w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w b / .2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h b w)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h alpha w / b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w w / w)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h b w)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple calc(h) calc(w) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple h w b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from rebeccapurple none w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) h w b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(none none none) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(none none none / none) h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(120deg none 50% / .5) h w b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(120deg 20% 50% / none) h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "hwb(from hwb(none 20% 50% / .5) h w b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(200 300 400 / 500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(-200 -300 -400 / -500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(from lab(25 20 50) l a b) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from color(display-p3 0 0 0) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) 35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l 35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a 35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) 35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l 35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a 35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) calc(l) calc(a) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(none none none) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(none none none / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 none 50) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(25 20 50 / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(2 3 4 / 500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from color(display-p3 0 0 0) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(none none none) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(none none none / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 none 0.5) l a b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(200 300 400 / 500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(-200 -300 -400 / -500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(from lch(0.7 45 30) l c h) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from color(display-p3 0 0 0) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lab(0.7 45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0deg)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0deg / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) 25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l 25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c 25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l 25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 50 120 400deg / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 50 120 -400deg / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) calc(l) calc(c) calc(h))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(none none none) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(none none none / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 none 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(0.7 45 30 / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(2 3 400 / 500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from color(display-p3 0 0 0) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklab(0.7 45 30) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0.25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0.25 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(none none none) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(none none none / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 none 30) l c h)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(srgb 0.7 0.5 0.3) srgb r g b) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4 / 5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4 / -5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400% / 500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400% / -500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 1.7 1.5 1.3) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 1.7 1.5 1.3) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb none none none) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb none none none / none) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 none 0.3) srgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / none) srgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4 / 5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4 / -5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400% / 500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400% / -500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear none none none) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear none none none / none) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 none 0.3) srgb-linear r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / none) srgb-linear r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4 / 5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4 / -5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400% / 500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400% / -500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb none none none) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb none none none / none) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 none 0.3) a98-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / none) a98-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4 / 5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4 / -5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400% / 500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400% / -500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 none none none) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 none none none / none) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 none 0.3) rec2020 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / none) rec2020 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4 / 5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4 / -5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400% / 500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400% / -500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb none none none) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb none none none / none) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 none 0.3) prophoto-rgb r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / none) prophoto-rgb r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0.2 g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 20% g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0.2 b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 20% b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 20% / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4 / 5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4 / -5)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400% / 500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400% / -500%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 g b r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 b alpha r / g)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r r r / r)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 alpha alpha alpha / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 calc(r) calc(g) calc(b))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 calc(r) calc(g) calc(b) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 none none none) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 none none none / none) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 none 0.3) display-p3 r g b)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / none) display-p3 r g b / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz y z x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x x x / x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz none none none) xyz x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz none none none / none) xyz x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 none 100) xyz x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz 7 -20.5 100 / none) xyz x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z) xyz-d50 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0.2 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0.2 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0.2 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0.2 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 y z x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x x x / x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 y z x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x x x / x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 calc(x) calc(y) calc(z))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 calc(x) calc(y) calc(z) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 none none none) xyz-d50 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 none none none / none) xyz-d50 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 none 100) xyz-d50 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / none) xyz-d50 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z) xyz-d65 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0 / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0.2 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0.2 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 20%)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0.2 y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0.2 z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0.2 / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0.2)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 y z x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x x x / x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 y z x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x x x / x)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 calc(x) calc(y) calc(z))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 calc(x) calc(y) calc(z) / calc(alpha))" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y none / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / none)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 none none none) xyz-d65 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 none none none / none) xyz-d65 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 none 100) xyz-d65 x y z)" should set the property value assert_not_equals: property should be set got disallowed value "" -FAIL e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / none) xyz-d65 x y z / alpha)" should set the property value assert_not_equals: property should be set got disallowed value "" +Found 961 tests; 902 PASS, 59 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS e.style['color'] = "rgb(from rebeccapurple r g b)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(from rebeccapurple r g b) r g b)" should set the property value +FAIL e.style['color'] = "rgb(from color(display-p3 0 1 0) r g b / alpha)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 249, 66)" but got "rgb(0, 255, 0)" +FAIL e.style['color'] = "rgb(from lab(100 104.3 -50.9) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 150, 255)" +FAIL e.style['color'] = "rgb(from lab(0 104.3 -50.9) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(42, 0, 34)" but got "rgb(90, 0, 76)" +FAIL e.style['color'] = "rgb(from lch(100 116 334) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 150, 255)" +FAIL e.style['color'] = "rgb(from lch(0 116 334) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(42, 0, 34)" but got "rgb(90, 0, 76)" +FAIL e.style['color'] = "rgb(from oklab(1 0.365 -0.16) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 92, 255)" +FAIL e.style['color'] = "rgb(from oklab(0 0.365 -0.16) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "rgb(19, 0, 24)" +FAIL e.style['color'] = "rgb(from oklch(1 0.399 336.3) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 91, 255)" +FAIL e.style['color'] = "rgb(from oklch(0 0.399 336.3) r g b)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "rgb(20, 0, 24)" +PASS e.style['color'] = "rgb(from rebeccapurple 0 0 0)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 0 g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 0 b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g 0 / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g b / 0)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 25 g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 25 b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g 25 / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g b / .25)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 20% g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 20% b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g 20% / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g b / 20%)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 25 g b / 25%)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 25 b / 25%)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g 25 / 25%)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple g b r)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple b alpha r / g)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r r r / r)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple alpha alpha alpha / alpha)" should set the property value +FAIL e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) g b r)" should set the property value assert_equals: serialization should be canonical expected "rgb(102, 153, 51)" but got "rgba(102, 153, 51, 0.8)" +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 20% 10)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r 10 20%)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple 0% 10 10)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r calc(g * 2) 10)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple b calc(r * .5) 10)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple none none none)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple none none none / none)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g none)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g none / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rebeccapurple r g b / none)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20% 40% 60% / 80%) r g b / none)" should set the property value +PASS e.style['color'] = "rgb(from rgb(none none none) r g b)" should set the property value +PASS e.style['color'] = "rgb(from rgb(none none none / none) r g b / alpha)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20% none 60%) r g b)" should set the property value +PASS e.style['color'] = "rgb(from rgb(20% 40% 60% / none) r g b / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s l)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(from rebeccapurple h s l) h s l)" should set the property value +FAIL e.style['color'] = "hsl(from color(display-p3 0 1 0) h s l / alpha)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 249, 66)" but got "rgb(0, 255, 0)" +FAIL e.style['color'] = "hsl(from lab(100 104.3 -50.9) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 150, 255)" +FAIL e.style['color'] = "hsl(from lab(0 104.3 -50.9) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(42, 0, 34)" but got "rgb(90, 0, 76)" +FAIL e.style['color'] = "hsl(from lch(100 116 334) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 150, 255)" +FAIL e.style['color'] = "hsl(from lch(0 116 334) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(42, 0, 34)" but got "rgb(90, 0, 76)" +FAIL e.style['color'] = "hsl(from oklab(1 0.365 -0.16) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 92, 255)" +FAIL e.style['color'] = "hsl(from oklab(0 0.365 -0.16) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "rgb(19, 0, 24)" +FAIL e.style['color'] = "hsl(from oklch(1 0.399 336.3) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 91, 255)" +FAIL e.style['color'] = "hsl(from oklch(0 0.399 336.3) h s l)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "rgb(20, 0, 24)" +PASS e.style['color'] = "hsl(from rebeccapurple 0 0% 0%)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 0deg 0% 0%)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 0 0% 0% / 0)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 0deg 0% 0% / 0)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 0 s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 0deg s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h 0% l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s 0% / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s l / 0)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 25 s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple 25deg s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h 20% l / alpha)" should set the property value +FAIL e.style['color'] = "hsl(from rebeccapurple h s 20% / alpha)" should set the property value assert_equals: serialization should be canonical expected "rgb(51, 25, 77)" but got "rgb(51, 26, 77)" +PASS e.style['color'] = "hsl(from rebeccapurple h s l / .25)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)" should set the property value +FAIL e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)" should set the property value assert_equals: serialization should be canonical expected "rgba(25, 51, 77, 0.8)" but got "rgba(26, 51, 77, 0.8)" +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h l s)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h alpha l / s)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h l l / l)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h l s)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple calc(h) calc(s) calc(l))" should set the property value +PASS e.style['color'] = "hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple none none none)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple none none none / none)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s none)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s none / alpha)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple h s l / none)" should set the property value +PASS e.style['color'] = "hsl(from rebeccapurple none s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) h s l / none)" should set the property value +PASS e.style['color'] = "hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(none none none) h s l)" should set the property value +PASS e.style['color'] = "hsl(from hsl(none none none / none) h s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(120deg none 50% / .5) h s l)" should set the property value +PASS e.style['color'] = "hsl(from hsl(120deg 20% 50% / none) h s l / alpha)" should set the property value +PASS e.style['color'] = "hsl(from hsl(none 20% 50% / .5) h s l / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w b)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hwb(from rebeccapurple h w b) h w b)" should set the property value +FAIL e.style['color'] = "hwb(from color(display-p3 0 1 0) h w b / alpha)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 249, 66)" but got "rgb(0, 255, 0)" +FAIL e.style['color'] = "hwb(from lab(100 104.3 -50.9) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 150, 255)" +FAIL e.style['color'] = "hwb(from lab(0 104.3 -50.9) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(42, 0, 34)" but got "rgb(90, 0, 76)" +FAIL e.style['color'] = "hwb(from lch(100 116 334) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 150, 255)" +FAIL e.style['color'] = "hwb(from lch(0 116 334) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(42, 0, 34)" but got "rgb(90, 0, 76)" +FAIL e.style['color'] = "hwb(from oklab(1 0.365 -0.16) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 92, 255)" +FAIL e.style['color'] = "hwb(from oklab(0 0.365 -0.16) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "rgb(19, 0, 24)" +FAIL e.style['color'] = "hwb(from oklch(1 0.399 336.3) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(255, 255, 255)" but got "rgb(255, 91, 255)" +FAIL e.style['color'] = "hwb(from oklch(0 0.399 336.3) h w b)" should set the property value assert_equals: serialization should be canonical expected "rgb(0, 0, 0)" but got "rgb(20, 0, 24)" +PASS e.style['color'] = "hwb(from rebeccapurple 0 0% 0%)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 0deg 0% 0%)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 0 0% 0% / 0)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 0deg 0% 0% / 0)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 0 w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 0deg w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h 0% b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w 0% / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w b / 0)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 25 w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple 25deg w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h 20% b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w 20% / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w b / .2)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h b w)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h alpha w / b)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w w / w)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h b w)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple calc(h) calc(w) calc(b))" should set the property value +PASS e.style['color'] = "hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple none none none)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple none none none / none)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w none)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w none / alpha)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple h w b / none)" should set the property value +PASS e.style['color'] = "hwb(from rebeccapurple none w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) h w b / none)" should set the property value +PASS e.style['color'] = "hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hwb(none none none) h w b)" should set the property value +PASS e.style['color'] = "hwb(from hwb(none none none / none) h w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hwb(120deg none 50% / .5) h w b)" should set the property value +PASS e.style['color'] = "hwb(from hwb(120deg 20% 50% / none) h w b / alpha)" should set the property value +PASS e.style['color'] = "hwb(from hwb(none 20% 50% / .5) h w b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a b)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(200 300 400 / 500%) l a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(-200 -300 -400 / -500%) l a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(from lab(25 20 50) l a b) l a b)" should set the property value +PASS e.style['color'] = "lab(from color(display-p3 0 0 0) l a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) 0 0 0)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) 0 a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l 0 b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a 0 / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a b / 0)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) 0 a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l 0 b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a 0 / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / 0)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) 35 a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l 35 b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a 35 / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a b / .35)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) 35 a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l 35 b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a 35 / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / .35)" should set the property value +FAIL e.style['color'] = "lab(from lab(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value assert_equals: serialization should be canonical expected "lab(200 300 400)" but got "lab(100 300 400)" +PASS e.style['color'] = "lab(from lab(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l b a)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a a / a)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l b a)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a a / a)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) calc(l) calc(a) calc(b))" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) none none none)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) none none none / none)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a none)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a none / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50) l a b / none)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a none / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / 40%) l a b / none)" should set the property value +PASS e.style['color'] = "lab(from lab(none none none) l a b)" should set the property value +PASS e.style['color'] = "lab(from lab(none none none / none) l a b / alpha)" should set the property value +PASS e.style['color'] = "lab(from lab(25 none 50) l a b)" should set the property value +PASS e.style['color'] = "lab(from lab(25 20 50 / none) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(2 3 4 / 500%) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(-2 -3 -4 / -500%) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(from oklab(0.25 0.2 0.5) l a b) l a b)" should set the property value +PASS e.style['color'] = "oklab(from color(display-p3 0 0 0) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0 a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l 0 b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a 0 / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / 0)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0 a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0 b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0 / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / 0)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) 0.35 a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l 0.35 b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a 0.35 / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / .35)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) 0.35 a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l 0.35 b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a 0.35 / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / .35)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.7 0.45 0.3 / 40%) 2 3 4 / 500)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.7 0.45 0.3 / 40%) -2 -3 -4 / -500)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l b a)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a a / a)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l b a)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a a / a)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) calc(l) calc(a) calc(b))" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) calc(l) calc(a) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) none none none)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) none none none / none)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a none)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a none / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5) l a b / none)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a none / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / 40%) l a b / none)" should set the property value +PASS e.style['color'] = "oklab(from oklab(none none none) l a b)" should set the property value +PASS e.style['color'] = "oklab(from oklab(none none none / none) l a b / alpha)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 none 0.5) l a b)" should set the property value +PASS e.style['color'] = "oklab(from oklab(0.25 0.2 0.5 / none) l a b / alpha)" should set the property value +FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha b a / l)" should set the property value assert_equals: serialization should be canonical expected "lab(100 30 45 / 0.7)" but got "lab(1 30 45 / 0.7)" +FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha a b / alpha)" should set the property value assert_equals: serialization should be canonical expected "lab(100 45 30)" but got "lab(1 45 30)" +FAIL e.style['color'] = "lab(from lab(.7 45 30) alpha a a / alpha)" should set the property value assert_equals: serialization should be canonical expected "lab(100 45 45)" but got "lab(1 45 45)" +FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha b a / l)" should set the property value assert_equals: serialization should be canonical expected "lab(40 30 45 / 0.7)" but got "lab(0.4 30 45 / 0.7)" +FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha a b / alpha)" should set the property value assert_equals: serialization should be canonical expected "lab(40 45 30 / 0.4)" but got "lab(0.4 45 30 / 0.4)" +FAIL e.style['color'] = "lab(from lab(.7 45 30 / 40%) alpha a a / alpha)" should set the property value assert_equals: serialization should be canonical expected "lab(40 45 45 / 0.4)" but got "lab(0.4 45 45 / 0.4)" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha b a / l)" should set the property value assert_equals: serialization should be canonical expected "oklab(1 0.3 0.45 / 0.7)" but got "oklab(0.01 0.3 0.45)" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha a b / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklab(1 0.45 0.3)" but got "oklab(0.01 0.45 0.3)" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3) alpha a a / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklab(1 0.45 0.45)" but got "oklab(0.01 0.45 0.45)" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha b a / l)" should set the property value assert_equals: serialization should be canonical expected "oklab(0.4 0.3 0.45 / 0.7)" but got "oklab(0.004 0.3 0.45)" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a b / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklab(0.4 0.45 0.3 / 0.4)" but got "oklab(0.004 0.45 0.3 / 0.4)" +FAIL e.style['color'] = "oklab(from oklab(.7 0.45 0.3 / 40%) alpha a a / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklab(0.4 0.45 0.45 / 0.4)" but got "oklab(0.004 0.45 0.45 / 0.4)" +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c h)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(200 300 400 / 500%) l c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(-200 -300 -400 / -500%) l c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(from lch(0.7 45 30) l c h) l c h)" should set the property value +PASS e.style['color'] = "lch(from color(display-p3 0 0 0) l c h / alpha)" should set the property value +FAIL e.style['color'] = "lch(from lab(0.7 45 30) l c h / alpha)" should set the property value assert_equals: serialization should be canonical expected "lch(0.7 54.08327 33.690067)" but got "lch(0.7 54.0833 33.6901)" +PASS e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0deg)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) 0 0 0deg / 0)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) 0 c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l 0 h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c 0 / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c 0deg / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c h / 0)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 0 c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l 0 h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 0 / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 0deg / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / 0)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) 25 c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l 25 h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c 25 / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c 25deg / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c h / .25)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 25 c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l 25 h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 25 / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c 25deg / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / .25)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 200 300 400 / 500)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) -200 -300 -400 / -500)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 50 120 400deg / 500)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) 50 120 -400deg / -500)" should set the property value +PASS e.style['color'] = "lch(from lch(.7 45 30) l c c / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(.7 45 30 / 40%) l c c / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) calc(l) calc(c) calc(h))" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) none none none)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) none none none / none)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c none)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c none / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30) l c h / none)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c none / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / 40%) l c h / none)" should set the property value +PASS e.style['color'] = "lch(from lch(none none none) l c h)" should set the property value +PASS e.style['color'] = "lch(from lch(none none none / none) l c h / alpha)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 none 30) l c h)" should set the property value +PASS e.style['color'] = "lch(from lch(0.7 45 30 / none) l c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(2 3 400 / 500%) l c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(-2 -3 -400 / -500%) l c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(from oklch(0.7 0.45 30) l c h) l c h)" should set the property value +PASS e.style['color'] = "oklch(from color(display-p3 0 0 0) l c h / alpha)" should set the property value +FAIL e.style['color'] = "oklch(from oklab(0.7 45 30) l c h / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklch(0.7 54.08327 33.690067)" but got "oklch(0.7 54.0833 33.6901)" +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 0 0deg / 0)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0 c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l 0 h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0 / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0deg / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / 0)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0 c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0 h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0 / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0deg / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / 0)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) 0.25 c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l 0.25 h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 0.25 / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c 25deg / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / .25)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.25 c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l 0.25 h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 0.25 / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c 25deg / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / .25)" should set the property value +FAIL e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 2 3 400 / 500)" should set the property value assert_equals: serialization should be canonical expected "oklch(2 3 40)" but got "oklch(1 3 40)" +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) -2 -3 -400 / -500)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 400deg / 500)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) 0.5 1.2 -400deg / -500)" should set the property value +PASS e.style['color'] = "oklch(from oklch(.7 0.45 30) l c c / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) l c c / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) calc(l) calc(c) calc(h))" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) none none none)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) none none none / none)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c none)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c none / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30) l c h / none)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c none / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / 40%) l c h / none)" should set the property value +PASS e.style['color'] = "oklch(from oklch(none none none) l c h)" should set the property value +PASS e.style['color'] = "oklch(from oklch(none none none / none) l c h / alpha)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 none 30) l c h)" should set the property value +PASS e.style['color'] = "oklch(from oklch(0.7 0.45 30 / none) l c h / alpha)" should set the property value +FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c h / l)" should set the property value assert_equals: serialization should be canonical expected "lch(100 45 30 / 0.7)" but got "lch(1 45 30 / 0.7)" +FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c h / alpha)" should set the property value assert_equals: serialization should be canonical expected "lch(100 45 30)" but got "lch(1 45 30)" +FAIL e.style['color'] = "lch(from lch(.7 45 30) alpha c c / alpha)" should set the property value assert_equals: serialization should be canonical expected "lch(100 45 45)" but got "lch(1 45 45)" +FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c h / l)" should set the property value assert_equals: serialization should be canonical expected "lch(40 45 30 / 0.7)" but got "lch(0.4 45 30 / 0.7)" +FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c h / alpha)" should set the property value assert_equals: serialization should be canonical expected "lch(40 45 30 / 0.4)" but got "lch(0.4 45 30 / 0.4)" +FAIL e.style['color'] = "lch(from lch(.7 45 30 / 40%) alpha c c / alpha)" should set the property value assert_equals: serialization should be canonical expected "lch(40 45 45 / 0.4)" but got "lch(0.4 45 45 / 0.4)" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c h / l)" should set the property value assert_equals: serialization should be canonical expected "oklch(1 0.45 30 / 0.7)" but got "oklch(0.01 0.45 30)" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c h / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklch(1 0.45 30)" but got "oklch(0.01 0.45 30)" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30) alpha c c / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklch(1 0.45 0.45)" but got "oklch(0.01 0.45 0.45)" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / l)" should set the property value assert_equals: serialization should be canonical expected "oklch(0.4 0.45 30 / 0.7)" but got "oklch(0.004 0.45 30)" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c h / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklch(0.4 0.45 30 / 0.4)" but got "oklch(0.004 0.45 30 / 0.4)" +FAIL e.style['color'] = "oklch(from oklch(.7 0.45 30 / 40%) alpha c c / alpha)" should set the property value assert_equals: serialization should be canonical expected "oklch(0.4 0.45 0.45 / 0.4)" but got "oklch(0.004 0.45 0.45 / 0.4)" +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(srgb 0.7 0.5 0.3) srgb r g b) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 2 3 4 / 5)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -2 -3 -4 / -5)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400%)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb 200% 300% 400% / 500%)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400%)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb -200% -300% -400% / -500%)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb g b r)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb g b r)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 1.7 1.5 1.3) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb 1.7 1.5 1.3) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb 1.7 1.5 1.3 / 140%) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb -0.7 -0.5 -0.3 / -40%) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb none none none)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g none)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3) srgb r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / 40%) srgb r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(srgb none none none) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb none none none / none) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 none 0.3) srgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb 0.7 0.5 0.3 / none) srgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 2 3 4 / 5)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -2 -3 -4 / -5)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400%)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear 200% 300% 400% / 500%)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400%)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear -200% -300% -400% / -500%)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear g b r)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear g b r)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 1.7 1.5 1.3 / 140%) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear -0.7 -0.5 -0.3 / -40%) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / 40%) srgb-linear r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear none none none) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear none none none / none) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 none 0.3) srgb-linear r g b)" should set the property value +PASS e.style['color'] = "color(from color(srgb-linear 0.7 0.5 0.3 / none) srgb-linear r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 2 3 4 / 5)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -2 -3 -4 / -5)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400%)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb 200% 300% 400% / 500%)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400%)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb -200% -300% -400% / -500%)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb g b r)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb g b r)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 1.7 1.5 1.3 / 140%) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb -0.7 -0.5 -0.3 / -40%) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / 40%) a98-rgb r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb none none none) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb none none none / none) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 none 0.3) a98-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(a98-rgb 0.7 0.5 0.3 / none) a98-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 2 3 4 / 5)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -2 -3 -4 / -5)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400%)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 200% 300% 400% / 500%)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400%)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 -200% -300% -400% / -500%)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 g b r)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 g b r)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 1.7 1.5 1.3 / 140%) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 -0.7 -0.5 -0.3 / -40%) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / 40%) rec2020 r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 none none none) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 none none none / none) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 none 0.3) rec2020 r g b)" should set the property value +PASS e.style['color'] = "color(from color(rec2020 0.7 0.5 0.3 / none) rec2020 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 2 3 4 / 5)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -2 -3 -4 / -5)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400%)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb 200% 300% 400% / 500%)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400%)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb -200% -300% -400% / -500%)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb g b r)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb g b r)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 1.7 1.5 1.3 / 140%) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb -0.7 -0.5 -0.3 / -40%) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / 40%) prophoto-rgb r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb none none none) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb none none none / none) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 none 0.3) prophoto-rgb r g b)" should set the property value +PASS e.style['color'] = "color(from color(prophoto-rgb 0.7 0.5 0.3 / none) prophoto-rgb r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 0.2 g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 20% g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 0.2 b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r 20% b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g 20% / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / 20%)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 2 3 4 / 5)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -2 -3 -4 / -5)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400%)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 200% 300% 400% / 500%)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400%)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 -200% -300% -400% / -500%)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 g b r)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 g b r)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 b alpha r / g)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r r r / r)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 alpha alpha alpha / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 1.7 1.5 1.3 / 140%) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 -0.7 -0.5 -0.3 / -40%) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 calc(r) calc(g) calc(b))" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 calc(r) calc(g) calc(b) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3) display-p3 r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / 40%) display-p3 r g b / none)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 none none none) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 none none none / none) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 none 0.3) display-p3 r g b)" should set the property value +PASS e.style['color'] = "color(from color(display-p3 0.7 0.5 0.3 / none) display-p3 r g b / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(xyz 7 -20.5 100) xyz x y z) xyz x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x 0 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz 0 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x 0 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz 0.2 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x 0.2 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / 20%)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz 0.2 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x 0.2 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz y z x)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x x x / x)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz y z x)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x x x / x)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz calc(x) calc(y) calc(z))" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz calc(x) calc(y) calc(z) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz none none none)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y none)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100) xyz x y z / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / 40%) xyz x y z / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz none none none) xyz x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz none none none / none) xyz x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 none 100) xyz x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz 7 -20.5 100 / none) xyz x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z) xyz-d50 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 0.2 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x 0.2 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / 20%)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 0.2 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x 0.2 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 y z x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x x x / x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 y z x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x x x / x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 calc(x) calc(y) calc(z))" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 calc(x) calc(y) calc(z) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100) xyz-d50 x y z / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / 40%) xyz-d50 x y z / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 none none none) xyz-d50 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 none none none / none) xyz-d50 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 none 100) xyz-d50 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d50 7 -20.5 100 / none) xyz-d50 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z) xyz-d65 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 0 0 / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 0.2 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x 0.2 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / 20%)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 0.2 y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x 0.2 z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y 0.2 / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / 0.2)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 y z x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x x x / x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 y z x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x x x / x)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 calc(x) calc(y) calc(z))" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 calc(x) calc(y) calc(z) / calc(alpha))" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 none none none / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100) xyz-d65 x y z / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y none / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / 40%) xyz-d65 x y z / none)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 none none none) xyz-d65 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 none none none / none) xyz-d65 x y z / alpha)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 none 100) xyz-d65 x y z)" should set the property value +PASS e.style['color'] = "color(from color(xyz-d65 7 -20.5 100 / none) xyz-d65 x y z / alpha)" should set the property value PASS e.style['color'] = "rgb(from var(--bg-color) r g b / 80%)" should set the property value PASS e.style['color'] = "lch(from var(--color) calc(l / 2) c h)" should set the property value PASS e.style['color'] = "rgb(from var(--color) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11) calc(r * .3 + g * .59 + b * .11))" should set the property value PASS e.style['color'] = "lch(from var(--color) l 0 h)" should set the property value -FAIL e.style['color'] = "rgb(from indianred 255 g b)" should set the property value assert_not_equals: property should be set got disallowed value "" +PASS e.style['color'] = "rgb(from indianred 255 g b)" should set the property value PASS e.style['color'] = "hsl(from var(--accent) calc(h + 180deg) s l)" should set the property value PASS e.style['color'] = "lab(from var(--mycolor) l a b / 100%)" should set the property value PASS e.style['color'] = "lab(from var(--mycolor) l a b / calc(alpha * 0.8))" should set the property value PASS e.style['color'] = "lab(from var(--mycolor) l a b / calc(alpha - 20%))" should set the property value PASS e.style['color'] = "lab(from var(--mycolor) l 0 0)" should set the property value -FAIL e.style['color'] = "lch(from peru calc(l * 0.8) c h)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['color'] = "lch(from peru calc(l * 0.8) c h)" should set the property value assert_equals: serialization should be canonical expected "lch(49.80138 54.003296 63.680317)" but got "lch(49.7972 54.0177 63.6639)" PASS e.style['color'] = "LCH(from var(--accent) l c calc(h + 180deg))" should set the property value PASS e.style['color'] = "lch(from var(--mycolor) l 0 h)" should set the property value PASS e.style['color'] = "var(--mygray)" should set the property value
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/empty-elements-insertion-expected.txt b/third_party/blink/web_tests/external/wpt/editing/other/empty-elements-insertion-expected.txt index 74501ea..6bff876 100644 --- a/third_party/blink/web_tests/external/wpt/editing/other/empty-elements-insertion-expected.txt +++ b/third_party/blink/web_tests/external/wpt/editing/other/empty-elements-insertion-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. PASS Insert text into the inline element styled with border PASS Insert text into the inline element styled with padding -FAIL Insert text into the unstyled inline element promise_test: Unhandled rejection with value: object "Error: element event-dispatch intercepted error" +FAIL Insert text into the unstyled inline element promise_test: Unhandled rejection with value: object "Error: element click intercepted error" FAIL Insert text into the unstyled inline element with the styled ::before pseudoelement assert_greater_than: The text should be inserted into the <strong> element expected a number greater than 0 but got 0 FAIL Insert text into the unstyled inline element with the styled ::after pseudoelement assert_greater_than: The text should be inserted into the <strong> element expected a number greater than 0 but got 0 FAIL Insert text into the unstyled inline element with the styled ::before and ::after pseudoelements assert_greater_than: The text should be inserted into the <strong> element expected a number greater than 0 but got 0
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html index 8ea3c22b..e2cef0d 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html
@@ -1,12 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps1</title> +<h1>2d.text.fontVariantCaps1</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1.html index b610c224..56acfc6 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps1.html
@@ -1,17 +1,18 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps1-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="c"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps1</title> +<h1>2d.text.fontVariantCaps1</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "32px serif"; -ctx.fontVariantCaps = "small-caps"; -// This should render the same as font = "small-caps 32px serif". -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "32px serif"; + ctx.fontVariantCaps = "small-caps"; + // This should render the same as font = "small-caps 32px serif". + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2-unexpected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2-unexpected.html deleted file mode 100644 index c64f5d0..0000000 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2-unexpected.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c"></canvas> - -<script> -let ctx = c.getContext("2d"); -ctx.font = "32px serif"; -ctx.fillText("Hello World", 20, 100); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2.html index f9d42ac3..56efbb6 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps2.html
@@ -1,16 +1,32 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> -<link rel="mismatch" href="2d.text.fontVariantCaps2-unexpected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps2</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> -<canvas id="c"></canvas> +<h1>2d.text.fontVariantCaps2</h1> +<p class="desc">Testing small caps setting in fontVariant</p> + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -// "mismatch" test, to verify that small-caps does change the rendering. -ctx.fillText("Hello World", 20, 100); +var t = async_test("Testing small caps setting in fontVariant"); +_addTest(function(canvas, ctx) { + + ctx.font = "small-caps 32px serif"; + // "mismatch" test, to verify that small-caps does change the rendering. + smallCaps_len = ctx.measureText("Hello World").width; + + ctx.font = "32px serif"; + normalCaps_len = ctx.measureText("Hello World").width; + _assert(smallCaps_len != normalCaps_len, "smallCaps_len != normalCaps_len"); + +}); </script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html index 069fbfb..cf2d5ae 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html
@@ -1,12 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps3</title> +<h1>2d.text.fontVariantCaps3</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -ctx.fillText("hello world", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + ctx.fillText("hello world", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3.html index a90e0c29..c3d80d3e5 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps3.html
@@ -1,18 +1,19 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps3-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="c"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps3</title> +<h1>2d.text.fontVariantCaps3</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "32px serif"; -ctx.fontVariantCaps = "all-small-caps"; -// This should render the same as using font = "small-caps 32px serif" -// with all the underlying text in lowercase. -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "32px serif"; + ctx.fontVariantCaps = "all-small-caps"; + // This should render the same as using font = "small-caps 32px serif" + // with all the underlying text in lowercase. + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html index 069fbfb..3813fd3 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html
@@ -1,12 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps4</title> +<h1>2d.text.fontVariantCaps4</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -ctx.fillText("hello world", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + ctx.fillText("hello world", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4.html index b598fb6..1ee9053 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps4.html
@@ -1,18 +1,19 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps4-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="c"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps4</title> +<h1>2d.text.fontVariantCaps4</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -// fontVariantCaps overrides the small-caps setting from the font attribute -// (spec unclear, cf. https://github.com/whatwg/html/issues/8103) -ctx.fontVariantCaps = "all-small-caps"; -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + // fontVariantCaps overrides the small-caps setting from the font attribute + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "all-small-caps"; + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html index 8ea3c22b..4bda4ec 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html
@@ -1,12 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps5</title> +<h1>2d.text.fontVariantCaps5</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5.html index b871f7c..d80de4ea 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps5.html
@@ -1,18 +1,19 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps5-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="c"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps5</title> +<h1>2d.text.fontVariantCaps5</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "small-caps 32px serif"; -// fontVariantCaps 'normal' does not override the setting from the font attribute. -// (spec unclear, cf. https://github.com/whatwg/html/issues/8103) -ctx.fontVariantCaps = "normal"; -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + // fontVariantCaps 'normal' does not override the setting from the font attribute. + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "normal"; + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html index c64f5d0..af9c736 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html
@@ -1,12 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps6</title> +<h1>2d.text.fontVariantCaps6</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -ctx.font = "32px serif"; -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.font = "32px serif"; + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6.html index e7bbd29..c17fac1 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.fontVariantCaps6.html
@@ -1,18 +1,19 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML Canvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps6-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="c"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps6</title> +<h1>2d.text.fontVariantCaps6</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -let ctx = c.getContext("2d"); -// fontVariantCaps is reset when the font attribute is set. -// (spec unclear, cf. https://github.com/whatwg/html/issues/8103) -ctx.fontVariantCaps = "all-small-caps"; -ctx.font = "32px serif"; -ctx.fillText("Hello World", 20, 100); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // fontVariantCaps is reset when the font attribute is set. + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "all-small-caps"; + ctx.font = "32px serif"; + ctx.fillText("Hello World", 20, 100); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html index 942bcdec..e2cef0d 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html
@@ -1,16 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c1"></canvas> -<br> -<canvas id="c2"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps1</title> +<h1>2d.text.fontVariantCaps1</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -for (let c = 1; c <= 2; ++c) { - let ctx = document.getElementById("c" + c).getContext("2d"); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; ctx.fillText("Hello World", 20, 100); -} </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html index a2da7f5..3c216f0 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html
@@ -1,55 +1,21 @@ <!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps1-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="canvas1"></canvas> -<br> -<canvas id="canvas2"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps1</title> +<h1>2d.text.fontVariantCaps1</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -const testContent = ` + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + ctx.font = "32px serif"; ctx.fontVariantCaps = "small-caps"; + // This should render the same as font = "small-caps 32px serif". ctx.fillText("Hello World", 20, 100); -`; -// Draw to the first canvas using a worker: -const canvas1 = document.getElementById("canvas1"); -const offscreen1 = canvas1.transferControlToOffscreen(); -const workerScript = ` - onmessage = (evt) => { - const canvas = evt.data.canvas; - const ctx = canvas.getContext("2d"); - - ${testContent} - - self.postMessage("done"); - }; -`; - -const blob = new Blob([workerScript], {type: 'application/javascript'}); -const worker = new Worker(URL.createObjectURL(blob)); -worker.addEventListener('message', function(e) { - if (e.data == "done") { - // Draw to the second using a main-thread OffscreenCanvas: - const offscreen2 = new OffscreenCanvas(300, 150); - const ctx = offscreen2.getContext("2d"); - - eval(testContent); - - document.getElementById("canvas2") - .getContext("bitmaprenderer") - .transferFromImageBitmap(offscreen2.transferToImageBitmap()); - - document.documentElement.classList.remove("reftest-wait"); - } -}, false); - -worker.postMessage({ canvas: offscreen1 }, [offscreen1]); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html new file mode 100644 index 0000000..4bc1b36 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.text.fontVariantCaps1-expected.html"> +<title>Canvas test: 2d.text.fontVariantCaps1</title> +<h1>2d.text.fontVariantCaps1</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.font = "32px serif"; + ctx.fontVariantCaps = "small-caps"; + // This should render the same as font = "small-caps 32px serif". + ctx.fillText("Hello World", 20, 100); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html index 8a644fb..e5bcff18 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html
@@ -1,54 +1,33 @@ <!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> -<link rel="mismatch" href="2d.text.fontVariantCaps2-unexpected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.text.fontVariantCaps2</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> -<canvas id="canvas1"></canvas> -<br> -<canvas id="canvas2"></canvas> +<h1>2d.text.fontVariantCaps2</h1> +<p class="desc">Testing small caps setting in fontVariant</p> + <script> -const testContent = ` +var t = async_test("Testing small caps setting in fontVariant"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; - ctx.fillText("Hello World", 20, 100); -`; + // "mismatch" test, to verify that small-caps does change the rendering. + smallCaps_len = ctx.measureText("Hello World").width; -// Draw to the first canvas using a worker: -const canvas1 = document.getElementById("canvas1"); -const offscreen1 = canvas1.transferControlToOffscreen(); -const workerScript = ` - onmessage = (evt) => { - const canvas = evt.data.canvas; - const ctx = canvas.getContext("2d"); + ctx.font = "32px serif"; + normalCaps_len = ctx.measureText("Hello World").width; + _assert(smallCaps_len != normalCaps_len, "smallCaps_len != normalCaps_len"); + t.done(); - ${testContent} - - self.postMessage("done"); - }; -`; - -const blob = new Blob([workerScript], {type: 'application/javascript'}); -const worker = new Worker(URL.createObjectURL(blob)); -worker.addEventListener('message', function(e) { - if (e.data == "done") { - // Draw to the second using a main-thread OffscreenCanvas: - const offscreen2 = new OffscreenCanvas(300, 150); - const ctx = offscreen2.getContext("2d"); - - eval(testContent); - - document.getElementById("canvas2") - .getContext("bitmaprenderer") - .transferFromImageBitmap(offscreen2.transferToImageBitmap()); - - document.documentElement.classList.remove("reftest-wait"); - } -}, false); - -worker.postMessage({ canvas: offscreen1 }, [offscreen1]); +}); </script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js new file mode 100644 index 0000000..89f4f48c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js
@@ -0,0 +1,28 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.text.fontVariantCaps2 +// Description:Testing small caps setting in fontVariant +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Testing small caps setting in fontVariant"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + // "mismatch" test, to verify that small-caps does change the rendering. + smallCaps_len = ctx.measureText("Hello World").width; + + ctx.font = "32px serif"; + normalCaps_len = ctx.measureText("Hello World").width; + _assert(smallCaps_len != normalCaps_len, "smallCaps_len != normalCaps_len"); + t.done(); +}); +done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html index 8d96d0ab..cf2d5ae 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html
@@ -1,16 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c1"></canvas> -<br> -<canvas id="c2"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps3</title> +<h1>2d.text.fontVariantCaps3</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -for (let c = 1; c <= 2; ++c) { - let ctx = document.getElementById("c" + c).getContext("2d"); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; ctx.fillText("hello world", 20, 100); -} </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html index 665a176..48699a64 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html
@@ -1,55 +1,22 @@ <!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps3-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="canvas1"></canvas> -<br> -<canvas id="canvas2"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps3</title> +<h1>2d.text.fontVariantCaps3</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -const testContent = ` + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + ctx.font = "32px serif"; ctx.fontVariantCaps = "all-small-caps"; + // This should render the same as using font = "small-caps 32px serif" + // with all the underlying text in lowercase. ctx.fillText("Hello World", 20, 100); -`; -// Draw to the first canvas using a worker: -const canvas1 = document.getElementById("canvas1"); -const offscreen1 = canvas1.transferControlToOffscreen(); -const workerScript = ` - onmessage = (evt) => { - const canvas = evt.data.canvas; - const ctx = canvas.getContext("2d"); - - ${testContent} - - self.postMessage("done"); - }; -`; - -const blob = new Blob([workerScript], {type: 'application/javascript'}); -const worker = new Worker(URL.createObjectURL(blob)); -worker.addEventListener('message', function(e) { - if (e.data == "done") { - // Draw to the second using a main-thread OffscreenCanvas: - const offscreen2 = new OffscreenCanvas(300, 150); - const ctx = offscreen2.getContext("2d"); - - eval(testContent); - - document.getElementById("canvas2") - .getContext("bitmaprenderer") - .transferFromImageBitmap(offscreen2.transferToImageBitmap()); - - document.documentElement.classList.remove("reftest-wait"); - } -}, false); - -worker.postMessage({ canvas: offscreen1 }, [offscreen1]); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html new file mode 100644 index 0000000..cd5c1db8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.text.fontVariantCaps3-expected.html"> +<title>Canvas test: 2d.text.fontVariantCaps3</title> +<h1>2d.text.fontVariantCaps3</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.font = "32px serif"; + ctx.fontVariantCaps = "all-small-caps"; + // This should render the same as using font = "small-caps 32px serif" + // with all the underlying text in lowercase. + ctx.fillText("Hello World", 20, 100); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html index 8d96d0ab..3813fd3 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html
@@ -1,16 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c1"></canvas> -<br> -<canvas id="c2"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps4</title> +<h1>2d.text.fontVariantCaps4</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -for (let c = 1; c <= 2; ++c) { - let ctx = document.getElementById("c" + c).getContext("2d"); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; ctx.fillText("hello world", 20, 100); -} </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html index 84c5fbb..b1b81b8 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html
@@ -1,57 +1,22 @@ <!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps4-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="canvas1"></canvas> -<br> -<canvas id="canvas2"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps4</title> +<h1>2d.text.fontVariantCaps4</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -const testContent = ` + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; // fontVariantCaps overrides the small-caps setting from the font attribute // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) ctx.fontVariantCaps = "all-small-caps"; ctx.fillText("Hello World", 20, 100); -`; -// Draw to the first canvas using a worker: -const canvas1 = document.getElementById("canvas1"); -const offscreen1 = canvas1.transferControlToOffscreen(); -const workerScript = ` - onmessage = (evt) => { - const canvas = evt.data.canvas; - const ctx = canvas.getContext("2d"); - - ${testContent} - - self.postMessage("done"); - }; -`; - -const blob = new Blob([workerScript], {type: 'application/javascript'}); -const worker = new Worker(URL.createObjectURL(blob)); -worker.addEventListener('message', function(e) { - if (e.data == "done") { - // Draw to the second using a main-thread OffscreenCanvas: - const offscreen2 = new OffscreenCanvas(300, 150); - const ctx = offscreen2.getContext("2d"); - - eval(testContent); - - document.getElementById("canvas2") - .getContext("bitmaprenderer") - .transferFromImageBitmap(offscreen2.transferToImageBitmap()); - - document.documentElement.classList.remove("reftest-wait"); - } -}, false); - -worker.postMessage({ canvas: offscreen1 }, [offscreen1]); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html new file mode 100644 index 0000000..0bae66f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.text.fontVariantCaps4-expected.html"> +<title>Canvas test: 2d.text.fontVariantCaps4</title> +<h1>2d.text.fontVariantCaps4</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + // fontVariantCaps overrides the small-caps setting from the font attribute + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "all-small-caps"; + ctx.fillText("Hello World", 20, 100); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html index 942bcdec..4bda4ec 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html
@@ -1,16 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c1"></canvas> -<br> -<canvas id="c2"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps5</title> +<h1>2d.text.fontVariantCaps5</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -for (let c = 1; c <= 2; ++c) { - let ctx = document.getElementById("c" + c).getContext("2d"); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; ctx.fillText("Hello World", 20, 100); -} </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html index 877d890c..2a6f7b5f 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html
@@ -1,57 +1,22 @@ <!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps5-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="canvas1"></canvas> -<br> -<canvas id="canvas2"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps5</title> +<h1>2d.text.fontVariantCaps5</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -const testContent = ` + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + ctx.font = "small-caps 32px serif"; // fontVariantCaps 'normal' does not override the setting from the font attribute. // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) ctx.fontVariantCaps = "normal"; ctx.fillText("Hello World", 20, 100); -`; -// Draw to the first canvas using a worker: -const canvas1 = document.getElementById("canvas1"); -const offscreen1 = canvas1.transferControlToOffscreen(); -const workerScript = ` - onmessage = (evt) => { - const canvas = evt.data.canvas; - const ctx = canvas.getContext("2d"); - - ${testContent} - - self.postMessage("done"); - }; -`; - -const blob = new Blob([workerScript], {type: 'application/javascript'}); -const worker = new Worker(URL.createObjectURL(blob)); -worker.addEventListener('message', function(e) { - if (e.data == "done") { - // Draw to the second using a main-thread OffscreenCanvas: - const offscreen2 = new OffscreenCanvas(300, 150); - const ctx = offscreen2.getContext("2d"); - - eval(testContent); - - document.getElementById("canvas2") - .getContext("bitmaprenderer") - .transferFromImageBitmap(offscreen2.transferToImageBitmap()); - - document.documentElement.classList.remove("reftest-wait"); - } -}, false); - -worker.postMessage({ canvas: offscreen1 }, [offscreen1]); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html new file mode 100644 index 0000000..8c59f5b5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.text.fontVariantCaps5-expected.html"> +<title>Canvas test: 2d.text.fontVariantCaps5</title> +<h1>2d.text.fontVariantCaps5</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.font = "small-caps 32px serif"; + // fontVariantCaps 'normal' does not override the setting from the font attribute. + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "normal"; + ctx.fillText("Hello World", 20, 100); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html index dbcb8ab..af9c736 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html
@@ -1,16 +1,15 @@ <!DOCTYPE html> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas reference</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> - -<canvas id="c1"></canvas> -<br> -<canvas id="c2"></canvas> - +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.text.fontVariantCaps6</title> +<h1>2d.text.fontVariantCaps6</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -for (let c = 1; c <= 2; ++c) { - let ctx = document.getElementById("c" + c).getContext("2d"); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + ctx.font = "32px serif"; ctx.fillText("Hello World", 20, 100); -} </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html index 08c70a3..c33684d 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html
@@ -1,57 +1,22 @@ <!DOCTYPE html> -<html class="reftest-wait"> -<meta charset="utf-8"> -<title>HTML OffscreenCanvas Test: the 'fontVariantCaps' property</title> -<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"> -<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fontvariantcaps"> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.text.fontVariantCaps6-expected.html"> -<meta name="assert" content="text rendering respects the fontVariantCaps property"> - -<canvas id="canvas1"></canvas> -<br> -<canvas id="canvas2"></canvas> - +<title>Canvas test: 2d.text.fontVariantCaps6</title> +<h1>2d.text.fontVariantCaps6</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -const testContent = ` + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + // fontVariantCaps is reset when the font attribute is set. // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) ctx.fontVariantCaps = "all-small-caps"; ctx.font = "32px serif"; ctx.fillText("Hello World", 20, 100); -`; -// Draw to the first canvas using a worker: -const canvas1 = document.getElementById("canvas1"); -const offscreen1 = canvas1.transferControlToOffscreen(); -const workerScript = ` - onmessage = (evt) => { - const canvas = evt.data.canvas; - const ctx = canvas.getContext("2d"); - - ${testContent} - - self.postMessage("done"); - }; -`; - -const blob = new Blob([workerScript], {type: 'application/javascript'}); -const worker = new Worker(URL.createObjectURL(blob)); -worker.addEventListener('message', function(e) { - if (e.data == "done") { - // Draw to the second using a main-thread OffscreenCanvas: - const offscreen2 = new OffscreenCanvas(300, 150); - const ctx = offscreen2.getContext("2d"); - - eval(testContent); - - document.getElementById("canvas2") - .getContext("bitmaprenderer") - .transferFromImageBitmap(offscreen2.transferToImageBitmap()); - - document.documentElement.classList.remove("reftest-wait"); - } -}, false); - -worker.postMessage({ canvas: offscreen1 }, [offscreen1]); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> -
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html new file mode 100644 index 0000000..47f70d8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.text.fontVariantCaps6-expected.html"> +<title>Canvas test: 2d.text.fontVariantCaps6</title> +<h1>2d.text.fontVariantCaps6</h1> +<p class="desc">Testing small caps setting in fontVariant</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + // fontVariantCaps is reset when the font attribute is set. + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "all-small-caps"; + ctx.font = "32px serif"; + ctx.fillText("Hello World", 20, 100); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml index 93c86b8..0e69cf2 100644 --- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml +++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml
@@ -1606,4 +1606,74 @@ ctx.fontStretch = "abcd"; @assert ctx.fontStretch === "ultra-expanded"; +- name: 2d.text.fontVariantCaps1 + desc: Testing small caps setting in fontVariant + code: | + ctx.font = "32px serif"; + ctx.fontVariantCaps = "small-caps"; + // This should render the same as font = "small-caps 32px serif". + ctx.fillText("Hello World", 20, 100); + reference: | + ctx.font = "small-caps 32px serif"; + ctx.fillText("Hello World", 20, 100); + +- name: 2d.text.fontVariantCaps2 + desc: Testing small caps setting in fontVariant + code: | + ctx.font = "small-caps 32px serif"; + // "mismatch" test, to verify that small-caps does change the rendering. + smallCaps_len = ctx.measureText("Hello World").width; + + ctx.font = "32px serif"; + normalCaps_len = ctx.measureText("Hello World").width; + @assert smallCaps_len != normalCaps_len; + +- name: 2d.text.fontVariantCaps3 + desc: Testing small caps setting in fontVariant + code: | + ctx.font = "32px serif"; + ctx.fontVariantCaps = "all-small-caps"; + // This should render the same as using font = "small-caps 32px serif" + // with all the underlying text in lowercase. + ctx.fillText("Hello World", 20, 100); + reference: | + ctx.font = "small-caps 32px serif"; + ctx.fillText("hello world", 20, 100); + +- name: 2d.text.fontVariantCaps4 + desc: Testing small caps setting in fontVariant + code: | + ctx.font = "small-caps 32px serif"; + // fontVariantCaps overrides the small-caps setting from the font attribute + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "all-small-caps"; + ctx.fillText("Hello World", 20, 100); + reference: | + ctx.font = "small-caps 32px serif"; + ctx.fillText("hello world", 20, 100); + +- name: 2d.text.fontVariantCaps5 + desc: Testing small caps setting in fontVariant + code: | + ctx.font = "small-caps 32px serif"; + // fontVariantCaps 'normal' does not override the setting from the font attribute. + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "normal"; + ctx.fillText("Hello World", 20, 100); + reference: | + ctx.font = "small-caps 32px serif"; + ctx.fillText("Hello World", 20, 100); + +- name: 2d.text.fontVariantCaps6 + desc: Testing small caps setting in fontVariant + code: | + // fontVariantCaps is reset when the font attribute is set. + // (spec unclear, cf. https://github.com/whatwg/html/issues/8103) + ctx.fontVariantCaps = "all-small-caps"; + ctx.font = "32px serif"; + ctx.fillText("Hello World", 20, 100); + reference: | + ctx.font = "32px serif"; + ctx.fillText("Hello World", 20, 100); + # TODO: shadows, alpha, composite, clip \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative-expected.txt new file mode 100644 index 0000000..73de097 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +FAIL Slots: Directionality: dir=rtl on slot assert_true: expected true got false +PASS Slots: Directionality: dir=rtl on host +PASS Slots: Directionality: dir=auto on host with Arabic shadow tree content +PASS Slots: Directionality: dir=auto in shadow tree with Arabic light tree content +PASS Slots: Directionality: dir=auto in shadow tree with Arabic shadow tree content +PASS Slots: Directionality: dir=auto on slot with Arabic light tree content +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative.html b/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative.html index 1f0dc07..5e8cedb 100644 --- a/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.tentative.html
@@ -2,9 +2,9 @@ <title>HTML Test: dir=auto|rtl with slots, and direction should be RTL</title> <meta charset="UTF-8"> <meta name="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com"> -<meta name="assert" content="When dir='auto', the direction is set according to - slot's assigned node. And the direction should be propagated to shadow" /> +<meta name="author" title="L. David Baron" href="mailto:dbaron@chromium.org"> <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute"/> +<link rel="help" href="https://github.com/whatwg/html/issues/3699"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <div id="host1"><span></span></div> @@ -12,27 +12,55 @@ <span id="host3" dir="auto"></span> <div id="host4">اختبر</div> <div id="host5"></div> +<div id="host6">اختبر</div> <script> -let root1 = host1.attachShadow({mode:"open"}); -root1.innerHTML = '<slot dir="rtl"></slot>'; - -let root2 = host2.attachShadow({mode:"open"}); -root2.innerHTML = '<span></span>'; - -let root3 = host3.attachShadow({mode:"open"}); -root3.innerHTML = `اختبر`; - -let root4 = host4.attachShadow({mode:"open"}); -root4.innerHTML = '<span dir="auto"><slot></slot></span>'; - -let root5 = host5.attachShadow({mode:"open"}); - root5.innerHTML = '<span dir="auto"><slot>اختبر</slot></span>'; test(() => { - assert_equals(getComputedStyle(host1.firstChild).direction, "rtl"); - assert_equals(getComputedStyle(root2.querySelector("span")).direction, "rtl"); - assert_equals(getComputedStyle(host3).direction, "ltr"); - assert_equals(getComputedStyle(root4.querySelector("span")).direction, "rtl"); - assert_equals(getComputedStyle(root5.querySelector("span")).direction, "rtl"); -}, 'Slots: Directionality'); + let root1 = host1.attachShadow({mode:"open"}); + root1.innerHTML = '<slot dir="rtl"></slot>'; + let span = host1.firstChild; + assert_equals(getComputedStyle(span).direction, "rtl"); + assert_true(span.matches(":dir(ltr)")); +}, 'Slots: Directionality: dir=rtl on slot'); + +test(() => { + let root2 = host2.attachShadow({mode:"open"}); + root2.innerHTML = '<span></span>'; + let span = root2.querySelector("span"); + assert_equals(getComputedStyle(span).direction, "rtl"); + assert_true(span.matches(":dir(rtl)")); +}, 'Slots: Directionality: dir=rtl on host'); + +test(() => { + let root3 = host3.attachShadow({mode:"open"}); + root3.innerHTML = `اختبر`; + let span = host3; + assert_equals(getComputedStyle(span).direction, "ltr"); + assert_true(span.matches(":dir(ltr)")); +}, 'Slots: Directionality: dir=auto on host with Arabic shadow tree content'); + +test(() => { + let root4 = host4.attachShadow({mode:"open"}); + root4.innerHTML = '<span dir="auto"><slot></slot></span>'; + let span = root4.querySelector("span"); + assert_equals(getComputedStyle(span).direction, "ltr"); + assert_true(span.matches(":dir(ltr)")); +}, 'Slots: Directionality: dir=auto in shadow tree with Arabic light tree content'); + +test(() => { + let root5 = host5.attachShadow({mode:"open"}); + root5.innerHTML = '<span dir="auto"><slot>اختبر</slot></span>'; + let span = root5.querySelector("span"); + assert_equals(getComputedStyle(span).direction, "rtl"); + assert_true(span.matches(":dir(rtl)")); +}, 'Slots: Directionality: dir=auto in shadow tree with Arabic shadow tree content'); + +test(() => { + let root6 = host6.attachShadow({mode:"open"}); + root6.innerHTML = '<slot dir="auto"></slot>'; + let span = root6.querySelector("slot"); + assert_equals(getComputedStyle(span).direction, "rtl"); + assert_true(span.matches(":dir(rtl)")); +}, 'Slots: Directionality: dir=auto on slot with Arabic light tree content'); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt index 92255d9..a46cb70 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/selection-pointer-expected.txt
@@ -6,7 +6,7 @@ PASS Selecting texts across <input type=datetime-local> should not cancel selection PASS Selecting texts across <input type=email> should not cancel selection PASS Selecting texts across <input type=file> should not cancel selection -FAIL Selecting texts across <input type=image> should not cancel selection promise_test: Unhandled rejection with value: object "Error: element event-dispatch intercepted error" +FAIL Selecting texts across <input type=image> should not cancel selection promise_test: Unhandled rejection with value: object "Error: element click intercepted error" PASS Selecting texts across <input type=month> should not cancel selection PASS Selecting texts across <input type=number> should not cancel selection PASS Selecting texts across <input type=password> should not cancel selection
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html.ini b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html.ini deleted file mode 100644 index 78cff02..0000000 --- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html.ini +++ /dev/null
@@ -1,3 +0,0 @@ -[first-paint-equals-lcp-text.html] - [FCP and LCP are the same when there is a single text element in the page.] - expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html index 3742791..d501ae0 100644 --- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html
@@ -1,124 +1,134 @@ <!doctype html> -<title>Pointer Events no-hover pointer attributes test</title> -<meta name="variant" content="?touch"> -<meta name="viewport" content="width=device-width"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/testdriver.js"></script> -<script src="/resources/testdriver-actions.js"></script> -<script src="/resources/testdriver-vendor.js"></script> -<script type="text/javascript" src="pointerevent_support.js"></script> -<style> - div { - height: 80px; - width: 80px; - } -</style> -<body onload="run()"> - <div id="square1"></div> - <iframe id="innerFrame" - src="resources/pointerevent_attributes_hoverable_pointers-iframe.html"> - </iframe> - <div id="done"></div> -</body> -<script> - 'use strict'; - const pointer_type = location.search.substring(1); - const test_pointer = pointer_type + "TestPointer"; +<html> + <head> + <title>Pointer Events properties tests</title> + <meta name="viewport" content="width=device-width"> + <link rel="stylesheet" type="text/css" href="pointerevent_styles.css"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <!-- Additional helper script for common checks across event types --> + <script type="text/javascript" src="pointerevent_support.js"></script> + <script> + var detected_pointertypes = {}; + var detected_eventTypes = {}; + var eventList = ['pointerover', 'pointerenter', 'pointerdown', 'pointerup', 'pointerout', 'pointerleave']; + // TODO(mustaq@chromium.org): missing touch pointermove coverage! + var expectedPointerId = NaN; - const logged_events = [ - "pointerover", "pointerenter", "pointerdown", - "pointerup", "pointerout", "pointerleave" - ]; + function resetTestState() { + detected_eventTypes = {}; + document.getElementById("square1").style.visibility = 'visible'; + document.getElementById('innerFrame').contentDocument.getElementById("square2").style.visibility = 'hidden'; + } + function checkPointerEventAttributes(event, targetBoundingClientRect, testNamePrefix) { + if (detected_eventTypes[event.type]) + return; + var expectedEventType = eventList[Object.keys(detected_eventTypes).length]; + detected_eventTypes[event.type] = true; + var pointerTestName = (testNamePrefix ? testNamePrefix + ' ' : '') + + expectedPointerType + ' ' + expectedEventType; - // TODO(mustaq@chromium.org): add pointermove coverage with touch-action:none. + detected_pointertypes[event.pointerType] = true; - function checkPointerEventAttributes(event, - expected_pointer_id, expected_event_type, - expected_bounding_rect) { - assert_equals(event.pointerType, pointer_type, - expected_event_type + ".pointerType should match test input"); + test(function() { + assert_equals(event.type, expectedEventType); + }, pointerTestName + ".type should be " + expectedEventType); - assert_equals(event.pointerId, expected_pointer_id, - expected_event_type + ".pointerId should match all other events"); - assert_equals(event.type, expected_event_type, - expected_event_type + ".type should be " + expected_event_type); + // Test button and buttons + test(function() { + assert_equals(event.button, 0); + }, pointerTestName + ".button attribute is 0 on touch-down."); - assert_equals(event.button, 0, - expected_event_type + ".button should be 0"); + if (event.type == 'pointerdown' || event.type == 'pointerover' || event.type == 'pointerenter') { + test(function() { + assert_equals(event.buttons, 1); + }, pointerTestName + ".buttons attribute is 1 on touch-down."); + } else { + test(function() { + assert_equals(event.buttons, 0); + }, pointerTestName + ".buttons is 0 on touch-release."); + } - if (['pointerover', 'pointerenter', 'pointerdown'].includes(event.type)) { - assert_equals(event.buttons, 1, - expected_event_type + ".buttons should be 1"); - } else { - assert_equals(event.buttons, 0, - expected_event_type + ".buttons should be 0"); - } + // Test clientX and clientY + test(function () { + assert_true(event.clientX >= targetBoundingClientRect.left && event.clientX < targetBoundingClientRect.right && event.clientY >= targetBoundingClientRect.top && event.clientY < targetBoundingClientRect.bottom); + }, pointerTestName + ".clientX and .clientY attributes are correct."); - assert_true(event.clientX >= expected_bounding_rect.left && - event.clientX < expected_bounding_rect.right, - expected_event_type + ".clientX should be within bounding client rect."); + check_PointerEvent(event, testNamePrefix); - assert_true(event.clientY >= expected_bounding_rect.top && - event.clientY < expected_bounding_rect.bottom, - expected_event_type + ".clientY should be within bounding client rect."); + // Test isPrimary + test(function () { + assert_equals(event.isPrimary, true); + }, pointerTestName + ".isPrimary attribute is true."); - check_PointerEvent(event, expected_event_type); + // Test pointerId value + if (isNaN(expectedPointerId)) { + expectedPointerId = event.pointerId; + } else { + test(function () { + assert_equals(event.pointerId, expectedPointerId); + }, pointerTestName + ".pointerId should be the same as previous pointer events for this active pointer."); + } + } - assert_equals(event.isPrimary, true, - expected_event_type + ".isPrimary is true."); - } + async function run() { + var test_pointerEvent = setup_pointerevent_test("pointerevent attributes", ['touch']); + var square1 = document.getElementById("square1"); + var rectSquare1 = square1.getBoundingClientRect(); + var innerFrame = document.getElementById('innerFrame'); + var square2 = innerFrame.contentDocument.getElementById('square2'); + var rectSquare2 = square2.getBoundingClientRect(); - async function checkEventsOnTarget(test, elem) { - const done = document.getElementById("done"); + eventList.forEach(function(eventName) { + on_event(square1, eventName, function (event) { + if (square1.style.visibility == 'hidden') + return; + checkPointerEventAttributes(event, rectSquare1, ""); + if (Object.keys(detected_eventTypes).length == eventList.length) { + square1.style.visibility = 'hidden'; + detected_eventTypes = {}; + square2.style.visibility = 'visible'; + expectedPointerId = NaN; + } + }); + on_event(square2, eventName, function (event) { + checkPointerEventAttributes(event, rectSquare2, "Inner frame "); + if (Object.keys(detected_eventTypes).length == eventList.length) { + square2.style.visibility = 'hidden'; + test_pointerEvent.done(); + } + }); + }); - let logged_event_promises = []; - for (let i = 0; i < logged_events.length; i++) { - logged_event_promises.push(getEvent(logged_events[i], elem, test)); - } - let done_promise = getEvent("pointerup", done, test); + // Inject touch inputs. + await clickInTarget("touch", square1); + await clickInTarget("touch", square2); + } + </script> + </head> + <body onload="run()"> + <h1>Pointer Events no-hover pointer attributes test</h1> + <h2 id="pointerTypeDescription"></h2> + <h4> + Test Description: This test checks the properties of pointer events that do not support hover. + <ol> + <li>Tap the black square.</li> + <li>Then move it off the black square so that it disappears.</li> + <li>When the red square appears tap on that as well.</li> + </ol> - let actions = new test_driver.Actions(); - actions = actions - .addPointer(test_pointer, pointer_type) - .pointerMove(0, 0, {origin:elem, sourceName:test_pointer}) - .pointerDown({sourceName:test_pointer}) - .pointerUp({sourceName:test_pointer}) - .pointerMove(0, 0, {origin:done, sourceName:test_pointer}) - .pointerDown({sourceName:test_pointer}) - .pointerUp({sourceName:test_pointer}); - await actions.send(); - - let done_event = await done_promise; - - let expected_pointer_id; - - // All Promises in logged_event_promises are already resolved bynow. - for (let i = 0; i < logged_event_promises.length; i++) { - let event = await logged_event_promises[i]; - if (expected_pointer_id === undefined) { - expected_pointer_id = event.pointerId; - } - checkPointerEventAttributes(event, expected_pointer_id, - logged_events[i], elem.getBoundingClientRect()); - } - } - - function run() { - promise_test(async test => { - const target = document.getElementById("square1"); - checkEventsOnTarget(test, target); - }, "PointerEvent attributes"); - - promise_test(async test => { - const target = frames[0].document.getElementById("square2"); - - // In Chromium, `test_driver.Actions()` sent to a subframe does not work - // even though the `onload` event here fires after a sqame-origin - // subframe is loaded. Waiting for 2 animation frames resolves this. - await waitForAnimationFrames(2); - - checkEventsOnTarget(test, target); - }, "PointerEvent attributes in a subframe"); - } -</script> + Test passes if the proper behavior of the events is observed. + </h4> + <div id="square1" class="square"></div> + <iframe id="innerFrame" src="resources/pointerevent_attributes_hoverable_pointers-iframe.html"></iframe> + <div class="spacer"></div> + <div id="complete-notice"> + <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p> + <p>Refresh the page to run the tests again with a different pointer type.</p> + </div> + <div id="log"></div> + </body> +</html>
diff --git a/third_party/blink/web_tests/resources/testdriver-vendor.js b/third_party/blink/web_tests/resources/testdriver-vendor.js index 1334043..aed84e2 100644 --- a/third_party/blink/web_tests/resources/testdriver-vendor.js +++ b/third_party/blink/web_tests/resources/testdriver-vendor.js
@@ -248,7 +248,7 @@ var pointerInteractablePaintTree = getPointerInteractablePaintTree(element, frame); if (pointerInteractablePaintTree.length === 0 || !element.contains(pointerInteractablePaintTree[0])) { - return Promise.reject(new Error("element event-dispatch intercepted error")); + return Promise.reject(new Error("element click intercepted error")); } var rect = element.getClientRects()[0];
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt index d1b51b93..811de2d 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -932,6 +932,7 @@ property src property text property type +html element search html element section html element select property add
diff --git a/third_party/closure_compiler/externs/accessibility_private.js b/third_party/closure_compiler/externs/accessibility_private.js index 6600830e..9ffb4aa 100644 --- a/third_party/closure_compiler/externs/accessibility_private.js +++ b/third_party/closure_compiler/externs/accessibility_private.js
@@ -342,6 +342,13 @@ /** * @enum {string} */ +chrome.accessibilityPrivate.ToastType = { + DICTATION_NO_FOCUSED_TEXT_FIELD: 'dictationNoFocusedTextField', +}; + +/** + * @enum {string} + */ chrome.accessibilityPrivate.DlcType = { TTS_BN_BD: 'ttsBnBd', TTS_CS_CZ: 'ttsCsCz', @@ -658,6 +665,13 @@ chrome.accessibilityPrivate.isLacrosPrimary = function(callback) {}; /** + * Displays an accessibility-related toast. + * @param {!chrome.accessibilityPrivate.ToastType} type The type of toast to + * show. + */ +chrome.accessibilityPrivate.showToast = function(type) {}; + +/** * Fired whenever ChromeVox should output introduction. * @type {!ChromeEvent} */
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index b047753..a3fdc1e 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-13-1-21-ga3f44aadb -Revision: a3f44aadbc5797b3e7a5a9f38473985eaf23d4cb +Version: VER-2-13-1-22-g97251fd5a +Revision: 97251fd5aa2a90041cf4f397a5e887b8d60ab0c2 CPEPrefix: cpe:/a:freetype:freetype:2.13.1 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium index 35b839c..d665bc5 100644 --- a/third_party/libaom/README.chromium +++ b/third_party/libaom/README.chromium
@@ -2,8 +2,8 @@ Short Name: libaom URL: https://aomedia.googlesource.com/aom/ Version: 0 -Date: Friday August 18 2023 -Revision: 584717120f2997bc29b1e9becce3322be01fc807 +Date: Monday August 21 2023 +Revision: 00ef4ff15e3e62c50e381eb00c08d7f709226d40 CPEPrefix: cpe:/a:aomedia:aomedia:3.6.1 License: BSD License File: source/libaom/LICENSE
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h index d22925d..605dfe9 100644 --- a/third_party/libaom/source/config/config/aom_version.h +++ b/third_party/libaom/source/config/config/aom_version.h
@@ -12,8 +12,8 @@ #define VERSION_MAJOR 3 #define VERSION_MINOR 6 #define VERSION_PATCH 1 -#define VERSION_EXTRA "1044-g584717120f" +#define VERSION_EXTRA "1053-g00ef4ff15e" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "3.6.1-1044-g584717120f" -#define VERSION_STRING " 3.6.1-1044-g584717120f" +#define VERSION_STRING_NOSP "3.6.1-1053-g00ef4ff15e" +#define VERSION_STRING " 3.6.1-1053-g00ef4ff15e"
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 0b6235f..f9c2ebfd 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -1,8 +1,8 @@ Name: libvpx URL: https://chromium.googlesource.com/webm/libvpx Version: 0 -Date: Friday August 11 2023 -Revision: 335728c987b3164ff25c58c06d29eb49e19e21d4 +Date: Monday August 21 2023 +Revision: 24c0dcc8513b8c1ba4ffbf934a399f89de646ffe CPEPrefix: cpe:/a:webmproject:libvpx:1.13.0 License: BSD License File: source/libvpx/LICENSE
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 84ad8e28..9ec5be1 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 13 #define VERSION_PATCH 0 -#define VERSION_EXTRA "430-g335728c98" +#define VERSION_EXTRA "445-g24c0dcc85" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.13.0-430-g335728c98" -#define VERSION_STRING " v1.13.0-430-g335728c98" +#define VERSION_STRING_NOSP "v1.13.0-445-g24c0dcc85" +#define VERSION_STRING " v1.13.0-445-g24c0dcc85"
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium index e5133f59..e51917b 100644 --- a/third_party/nearby/README.chromium +++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@ Name: Nearby Connections Library Short Name: Nearby URL: https://github.com/google/nearby -Version: 945ab524852422d6632f139a939bbc1019c3ec7f +Version: ea7aa00e0cd99a0fab900ae55e727fd5acf672fd License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/tools/checkperms/checkperms.py b/tools/checkperms/checkperms.py index 949e380..449bd75 100755 --- a/tools/checkperms/checkperms.py +++ b/tools/checkperms/checkperms.py
@@ -412,7 +412,16 @@ class ApiGit(ApiAllFilesAtOnceBase): def _get_all_files(self): - return capture([git_name, 'ls-files'], cwd=self.root_dir).splitlines() + # ls-files -s outputs in the following format: + # <mode> <SP> <object> <SP> <stage> <TAB> <file> + # Example output: + # 100644 08f1a0445babd612aab0a9934eabc0a7ae3d48ef 0<TAB>README.md + # 160000 e9f9f56b0dee9032936d23c81c8246ae0ffe36bd 0<TAB>build + out = capture([git_name, 'ls-files', '-s'], cwd=self.root_dir).splitlines() + + # Return only actual files, which start with 100, and ignore anything else. + # See: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects + return [x.split(maxsplit=3)[-1] for x in out if x.startswith('100')] def get_scm(dir_path, bare):
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 04ad0f5e..82295d5 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -145,6 +145,7 @@ 'android-12l-x64-fyi-dbg': 'android_debug_static_bot_x64_reclient_webview_trichrome_webview_shell', 'android-13-x64-fyi-rel': 'android_release_bot_minimal_symbols_x64_fastbuild_webview_trichrome_reclient', 'android-annotator-rel': 'android_release_bot_minimal_symbols_arm64_webview_google_reclient', + 'android-chrome-pie-x86-wpt-android-specific': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient', 'android-chrome-pie-x86-wpt-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient', 'android-cronet-asan-x86-rel': 'android_cronet_release_bot_minimal_symbols_x86_clang_asan_reclient', 'android-weblayer-with-aosp-webview-x86-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_resource_allowlisting_disable_proguard_chrome_google_reclient', @@ -1031,6 +1032,7 @@ 'android-asan': 'android_clang_asan_release_trybot_reclient', 'android-bfcache-rel': 'android_release_trybot_x86_fastbuild_webview_monochrome_reclient', 'android-binary-size': 'android_binary_size_reclient', + 'android-chrome-pie-x86-wpt-android-specific': 'android_release_trybot_x86_fastbuild_webview_monochrome_reclient', 'android-chrome-pie-x86-wpt-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_monochrome_reclient', 'android-code-coverage': 'gpu_tests_android_release_bot_minimal_symbols_arm64_fastbuild_java_coverage_reclient', 'android-code-coverage-native': 'gpu_tests_android_release_bot_no_symbols_arm64_fastbuild_native_coverage_reclient',
diff --git a/tools/mb/mb_config_expectations/chromium.android.fyi.json b/tools/mb/mb_config_expectations/chromium.android.fyi.json index 4aa0239..7a176cf 100644 --- a/tools/mb/mb_config_expectations/chromium.android.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.android.fyi.json
@@ -63,6 +63,24 @@ "use_remoteexec": true } }, + "android-chrome-pie-x86-wpt-android-specific": { + "gn_args": { + "android_static_analysis": "off", + "dcheck_always_on": false, + "debuggable_apks": false, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "strip_debug_info": true, + "symbol_level": 1, + "system_webview_package_name": "com.google.android.apps.chrome", + "system_webview_shell_package_name": "org.chromium.my_webview_shell", + "target_cpu": "x86", + "target_os": "android", + "use_remoteexec": true + } + }, "android-chrome-pie-x86-wpt-fyi-rel": { "gn_args": { "android_static_analysis": "off",
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json index 2cb4208..813db62 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -232,6 +232,24 @@ "use_remoteexec": true } }, + "android-chrome-pie-x86-wpt-android-specific": { + "gn_args": { + "android_static_analysis": "off", + "dcheck_always_on": true, + "debuggable_apks": false, + "ffmpeg_branding": "Chrome", + "is_component_build": false, + "is_debug": false, + "proprietary_codecs": true, + "strip_debug_info": true, + "symbol_level": 0, + "system_webview_package_name": "com.google.android.apps.chrome", + "system_webview_shell_package_name": "org.chromium.my_webview_shell", + "target_cpu": "x86", + "target_os": "android", + "use_remoteexec": true + } + }, "android-chrome-pie-x86-wpt-fyi-rel": { "gn_args": { "android_static_analysis": "off",
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 7eab0d1..9ecbaf45 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -37589,6 +37589,8 @@ <int value="1818" label="OS_DIAGNOSTICS_RUNBLUETOOTHSCANNINGROUTINE"/> <int value="1819" label="OS_DIAGNOSTICS_RUNBLUETOOTHPAIRINGROUTINE"/> <int value="1820" label="FILEMANAGERPRIVATE_DISMISSIOTASK"/> + <int value="1821" label="ACCESSIBILITY_PRIVATE_SHOWTOAST"/> + <int value="1822" label="USERSCRIPTS_GETSCRIPTS"/> </enum> <enum name="ExtensionIconState"> @@ -60986,6 +60988,7 @@ <int value="-1727173228" label="OmniboxZeroSuggestionsOnNTP:enabled"/> <int value="-1726572968" label="WebViewCpuAffinityRestrictToLittleCores:disabled"/> + <int value="-1726047833" label="AutofillEnableServerIban:enabled"/> <int value="-1725507605" label="enable-web-midi"/> <int value="-1722208902" label="CCTModuleCustomRequestHeader:disabled"/> <int value="-1720654843" @@ -68419,6 +68422,7 @@ <int value="2005009211" label="OmniboxAdaptiveSuggestionsCount:disabled"/> <int value="2005012791" label="AblateSendPendingAccessibilityEvents:enabled"/> <int value="2005245012" label="SecurityInterstitialsDarkMode:disabled"/> + <int value="2005344314" label="AutofillEnableServerIban:disabled"/> <int value="2005614493" label="tab-management-experiment-type-dill"/> <int value="2006413281" label="ContextualSuggestionsAlternateCardLayout:enabled"/> @@ -73759,6 +73763,15 @@ <int value="8" label="Unknown"/> </enum> +<enum name="NearbyPresenceFirstTimeRegistrationResult"> + <int value="0" label="Success"/> + <int value="1" label="Registration With Server Failure"/> + <int value="2" label="Credential Generation Failure"/> + <int value="3" label="Upload Local Credentials Failure"/> + <int value="4" label="Download Remote Credentials Failure"/> + <int value="5" label="Save Remote Credentials Failure"/> +</enum> + <enum name="NearbyShareArcBridgeFailResult"> <int value="0" label="Instance is null."/> <int value="1" label="Instance already exists."/> @@ -77776,6 +77789,8 @@ <int value="18" label="Scalable IPH Bubble"/> <int value="19" label="Video Conference Tray Camera And Microphone Use While Disabled"/> + <int value="20" label="Multitask Menu Clamshell"/> + <int value="21" label="Multitask Menu Tablet"/> </enum> <enum name="NukeProfileResult"> @@ -84858,6 +84873,11 @@ <int value="23" label="Hangup ongoing call response"/> <int value="24" label="Feature setup request"/> <int value="25" label="Feature setup response"/> + <int value="26" label="Ping request"/> + <int value="27" label="Ping response"/> + <int value="28" label="App stream update"/> + <int value="29" label="App list update"/> + <int value="30" label="App list incremental update"/> </enum> <enum name="PhoneHubNotificationAccessSetupStatus"> @@ -104470,6 +104490,7 @@ <int value="41" label="Video Conference Tray Speak-On-Mute Detected"/> <int value="42" label="Copy Gif To Clipboard Action"/> <int value="44" label="Battery Saver Disabled"/> + <int value="45" label="Dictation No Focused Text Field"/> </enum> <enum name="TokenBinding.KeyMatch">
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml index b2b69921..1bb5cf41 100644 --- a/tools/metrics/histograms/metadata/accessibility/histograms.xml +++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -1793,8 +1793,8 @@ <owner>kyungjunlee@google.com</owner> <owner>chrome-a11y-core@google.com</owner> <summary> - Records the number of pages in an inaccessible PDF opened for PDF OCR when a - PDF accessibility tree gets created for the PDF. + Records the number of pages in an inaccessible PDF when a PDF accessibility + tree gets created for the PDF. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 9b13bd82..9f0c925 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -5321,6 +5321,22 @@ </summary> </histogram> +<histogram name="Ash.PhantomWindowController.Show.PresentationTime" units="ms" + expires_after="2024-08-14"> + <owner>sammiequon@chromium.org</owner> + <owner>zxdan@chromium.org</owner> + <owner>chromeos-wm-corexp@google.com</owner> + <summary> + Records the presentation time, which is the time in milliseconds it takes + from when show phantom window was received and successfully processed to + when the next frame is shown to the user. The phantom window is shown to + give users an indication of the window bounds of the next state. For + example, when dragging a window to the left side of the display, the phantom + window will take up roughly the left half of the work area to indicate the + bounds of the window, if the drag is completed. + </summary> +</histogram> + <histogram name="Ash.Pip.AndroidPipUseTime" units="ms" expires_after="2024-01-06"> <owner>takise@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/nearby/histograms.xml b/tools/metrics/histograms/metadata/nearby/histograms.xml index f1defe1..cef83c0 100644 --- a/tools/metrics/histograms/metadata/nearby/histograms.xml +++ b/tools/metrics/histograms/metadata/nearby/histograms.xml
@@ -353,6 +353,45 @@ </summary> </histogram> +<histogram name="Nearby.Presence.Credentials.FirstTimeRegistration.Result" + enum="NearbyPresenceFirstTimeRegistrationResult" expires_after="2024-01-05"> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the result (success or failure reason) of the first time server + registration flow for Nearby Presence. The first time server registration + flow occurs only once per user per device. Emitted on failure or success of + the overall flow. + </summary> +</histogram> + +<histogram + name="Nearby.Presence.Credentials.FirstTimeServerRegistration.AttemptsNeededCount" + units="attempts" expires_after="2024-01-05"> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the total number of attempts of registering the local device with + the Nearby Presence Web Server during the first time registration flow. The + first time server registration flow occurs only once per user per device. + Emitted on success to reflect the final count of attempts required to + register with the server. No metric is emitted on failure. + </summary> +</histogram> + +<histogram + name="Nearby.Presence.Credentials.FirstTimeServerRegistration.FailureReason" + enum="NearbyHttpResult" expires_after="2024-01-05"> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the failure reason of a single attempt to register the local device + with the Nearby Presence Web Server. The first time server registration flow + occurs only once per user per device. Emitted after every unsuccessful + attempt to register with the server. No metric is emitted on success. + </summary> +</histogram> + <histogram name="Nearby.Presence.Credentials.Upload.AttemptsNeededCount" units="attempts" expires_after="2024-01-05"> <owner>julietlevesque@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml index c9dd276..355edad 100644 --- a/tools/metrics/histograms/metadata/uma/histograms.xml +++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -338,6 +338,18 @@ </token> </histogram> +<histogram name="UMA.InitialStabilityRecordBeacon" enum="Boolean" + expires_after="2024-08-22"> + <owner>mpearson@chromium.org</owner> + <owner>src/base/metrics/OWNERS</owner> + <summary> + Emitted (with value "true") in each UMA record that's an initial + stability log. Missing from other types of logs such as logs from ongoing + Chrome use and "independent" logs that contain data from the + previous session via the persistent histograms code. + </summary> +</histogram> + <histogram name="UMA.InitSequence" enum="UmaInitSequence" expires_after="2023-12-17"> <owner>asvitkine@chromium.org</owner>
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py index 739853e..fe19cc53 100755 --- a/tools/rust/build_rust.py +++ b/tools/rust/build_rust.py
@@ -55,7 +55,7 @@ from build import (AddCMakeToPath, AddZlibToPath, CheckoutGitRepo, DownloadDebianSysroot, GetLibXml2Dirs, LLVM_BUILD_TOOLS_DIR, - RunCommand) + RunCommand, ZStdDirs) from update import (CHROMIUM_DIR, DownloadAndUnpack, EnsureDirExists, GetDefaultHostOs, RmTree, UpdatePackage) @@ -298,7 +298,7 @@ runs. ''' def __init__(self, zlib_path, libxml2_dirs, build_mac_arm, debian_sysroot, - verbose): + verbose, zstd_dirs): self._env = collections.defaultdict(str, os.environ) self._build_mac_arm = build_mac_arm self._verbose = verbose @@ -374,6 +374,15 @@ self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += ( f' -Clink-arg={LD_PATH_FLAG}{libxml2_dirs.lib_dir}') + if zstd_dirs: + self._env['CFLAGS'] += f' -I{zstd_dirs.include_dir}' + self._env['CXXFLAGS'] += f' -I{zstd_dirs.include_dir}' + self._env['LDFLAGS'] += f' {LD_PATH_FLAG}{zstd_dirs.lib_dir}' + self._env['RUSTFLAGS_BOOTSTRAP'] += ( + f' -Clink-arg={LD_PATH_FLAG}{zstd_dirs.lib_dir}') + self._env['RUSTFLAGS_NOT_BOOTSTRAP'] += ( + f' -Clink-arg={LD_PATH_FLAG}{zstd_dirs.lib_dir}') + if debian_sysroot: # This mainly influences the glibc version that rustc itself needs. sysroot_cflag = f'--sysroot={debian_sysroot}' @@ -676,6 +685,10 @@ else: libxml2_dirs = None + # Require zstd compression. ZStd should be built altogether with llvm + # already. + zstd_dirs = ZStdDirs() + # TODO(crbug.com/1271215): OpenSSL is somehow already present on the Windows # builder, but we should change to using a package from 3pp when it is # available. @@ -685,7 +698,7 @@ AddOpenSSLToEnv(args.build_mac_arm) xpy = XPy(zlib_path, libxml2_dirs, args.build_mac_arm, debian_sysroot, - args.verbose) + args.verbose, zstd_dirs) if args.dump_env: with open('rust-build-env', 'w') as f:
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java b/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java index cf952fb7..97cdfd2f8 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java +++ b/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java
@@ -5,16 +5,25 @@ package org.chromium.ui.widget; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatImageView; +import org.chromium.base.Log; + // TODO(https://crbug.com/1400720): This class has no use now, so we can get rid of it. /** * A subclass of AppCompatImageView to add workarounds for bugs in Android Framework and Support * Library. */ public class ChromeImageView extends AppCompatImageView { + private static final String TAG = "CIV"; + public ChromeImageView(Context context) { super(context); } @@ -26,4 +35,17 @@ public ChromeImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } + + @Override + protected void onDraw(Canvas canvas) { + // Add extra method to stack and logging for https://crbug.com/1457791. + final @Nullable Drawable drawable = getDrawable(); + if (drawable != null && drawable instanceof BitmapDrawable) { + final @Nullable Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); + if (bitmap != null && bitmap.isRecycled()) { + Log.e(TAG, "Trying to draw with recycled BitmapDrawable. Id: " + getId()); + } + } + super.onDraw(canvas); + } }
diff --git a/ui/base/ime/ash/ime_bridge.h b/ui/base/ime/ash/ime_bridge.h index 6f3f3bc..0913d30 100644 --- a/ui/base/ime/ash/ime_bridge.h +++ b/ui/base/ime/ash/ime_bridge.h
@@ -87,7 +87,8 @@ base::ObserverList<IMEBridgeObserver> observers_; TextInputMethod::InputContext current_input_context_; - raw_ptr<IMECandidateWindowHandlerInterface, ExperimentalAsh> + raw_ptr<IMECandidateWindowHandlerInterface, + LeakedDanglingUntriaged | ExperimentalAsh> candidate_window_handler_ = nullptr; raw_ptr<IMEAssistiveWindowHandlerInterface, DanglingUntriaged | ExperimentalAsh>
diff --git a/ui/events/devices/device_data_manager.cc b/ui/events/devices/device_data_manager.cc index cf7b46d3..4e92bce 100644 --- a/ui/events/devices/device_data_manager.cc +++ b/ui/events/devices/device_data_manager.cc
@@ -161,6 +161,11 @@ return touchpad_devices_; } +const std::vector<InputDevice>& DeviceDataManager::GetGraphicsTabletDevices() + const { + return graphics_tablet_devices_; +} + const std::vector<InputDevice>& DeviceDataManager::GetUncategorizedDevices() const { return uncategorized_devices_;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc index 154cfe8..bdcf892 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -39,6 +39,8 @@ namespace { +constexpr uint32_t kNoModesConnectorId = 404; + // Create a basic mode for a 6x4 screen. const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; @@ -196,6 +198,12 @@ auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects( /*crtc_count=*/2, /*planes_per_crtc*/ 2, movable_planes); + + // Add one connected connector with no modes (sterile). + auto& connector_props = drm_state.AddConnector(); + connector_props.id = kNoModesConnectorId; + connector_props.connection = true; + drm_state.crtc_properties[0].properties.push_back( {.id = kVrrEnabledPropId, .value = 0}); drm_->InitializeState(drm_state, use_atomic); @@ -329,6 +337,23 @@ } } +TEST_F(MAYBE_HardwareDisplayControllerTest, + BadLinkStatusConnectorPropsAfterModeset) { + DrmOverlayPlaneList modeset_planes; + modeset_planes.emplace_back(CreateBuffer(), nullptr); + EXPECT_TRUE(ModesetWithPlanes(modeset_planes)); + + ScopedDrmObjectPropertyPtr bad_link_connector_props = + drm_->GetObjectProperties(kNoModesConnectorId, DRM_MODE_OBJECT_CONNECTOR); + { + DrmWrapper::Property prop = {}; + GetDrmPropertyForName(drm_.get(), bad_link_connector_props.get(), + "link-status", &prop); + EXPECT_EQ(kLinkStatusPropId, prop.id); + EXPECT_EQ(static_cast<uint64_t>(DRM_MODE_LINK_STATUS_BAD), prop.value); + } +} + TEST_F(MAYBE_HardwareDisplayControllerTest, PlanePropsAfterModeset) { const FakeFenceFD fake_fence_fd; DrmOverlayPlaneList modeset_planes;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc index 057e16a..7003dc2 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -267,7 +267,7 @@ base::flat_set<uint32_t> valid_ids; for (int i = 0; i < resources->count_connectors; ++i) { - uint32_t connector_id = resources->connectors[i]; + const uint32_t connector_id = resources->connectors[i]; ScopedDrmObjectPropertyPtr props( drm_->GetObjectProperties(connector_id, DRM_MODE_OBJECT_CONNECTOR)); @@ -276,9 +276,15 @@ << connector_id; continue; } + // Getting the connector is guaranteed if we survived getting the + // connector's properties. + ScopedDrmConnectorPtr connector = drm_->GetConnector(connector_id); + DCHECK(connector); ConnectorProperties state_props; state_props.id = connector_id; + state_props.connection = connector->connection; + state_props.count_modes = connector->count_modes; GetDrmPropertyForName(drm_, props.get(), "CRTC_ID", &state_props.crtc_id); DCHECK(!drm_->is_atomic() || state_props.crtc_id.id); GetDrmPropertyForName(drm_, props.get(), "link-status",
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h index 33055f3..92c349e 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -223,6 +223,8 @@ protected: struct ConnectorProperties { uint32_t id; + drmModeConnection connection; + int count_modes; DrmWrapper::Property crtc_id; DrmWrapper::Property link_status; };
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc index f3aa2252..994958f 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -102,12 +102,19 @@ // updated only after a successful modeset. ConnectorProperties connector_props = connectors_props_[*connector_index]; connector_props.crtc_id.value = crtc_id; - // Always set link-status to DRM_MODE_LINK_STATUS_GOOD. In case a link - // training has failed and link-status is now BAD, the kernel expects the - // userspace to reset it to GOOD; otherwise, it will ignore modeset requests - // which have the same mode as the reported bad status. + // Set link-status to DRM_MODE_LINK_STATUS_GOOD when a connector is connected + // and has modes. In case a link training has failed and link-status is now + // BAD, the kernel expects the userspace to reset it to GOOD; otherwise, it + // will ignore modeset requests which have the same mode as the reported bad + // status. However, if a connector is marked connected but has no modes, it + // effectively has a bandwidth of 0Gbps and failed all link training + // attempts. Leave it in link_status bad, since resetting the connector's + // resources in DRM should not be affected by this state. // https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties - connector_props.link_status.value = DRM_MODE_LINK_STATUS_GOOD; + if (connector_props.connection == DRM_MODE_CONNECTED && + connector_props.count_modes != 0) { + connector_props.link_status.value = DRM_MODE_LINK_STATUS_GOOD; + } bool status = AddPropertyIfValid(atomic_request, connector_id, connector_props.crtc_id);
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/ui/ozone/platform/drm/gpu/mock_drm_device.cc index 52d928b..21bba1c 100644 --- a/ui/ozone/platform/drm/gpu/mock_drm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -50,6 +50,9 @@ const std::vector<uint32_t> kBlobProperyIds = {kEdidBlobPropId}; +const ResolutionAndRefreshRate kStandardMode = + ResolutionAndRefreshRate{gfx::Size(1920, 1080), 60u}; + const std::map<uint32_t, std::string> kCrtcRequiredPropertyNames = { {kActivePropId, "ACTIVE"}, {kModePropId, "MODE_ID"}, @@ -227,7 +230,15 @@ MockDrmState state = CreateStateWithAllProperties(); std::vector<uint32_t> crtc_ids; for (size_t i = 0; i < crtc_count; ++i) { - const auto& crtc = state.AddCrtcAndConnector().first; + const auto& props = state.AddCrtcAndConnector(); + + // Add at least one mode, so the connector is not sterile. + ConnectorProperties& connector = props.second; + connector.connection = true; + connector.modes = std::vector<ResolutionAndRefreshRate>{kStandardMode}; + + // Add CRTC planes. + CrtcProperties& crtc = props.first; crtc_ids.push_back(crtc.id); state.AddPlane(crtc.id, DRM_PLANE_TYPE_PRIMARY); @@ -249,6 +260,7 @@ uint32_t next_connector_id = GetNextId(connector_properties, kConnectorIdBase); auto& connector_property = connector_properties.emplace_back(); + connector_property.connection = false; connector_property.id = next_connector_id; for (const auto& pair : kConnectorRequiredPropertyNames) { connector_property.properties.push_back({.id = pair.first, .value = 0}); @@ -389,12 +401,30 @@ } SetCapability(DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - MaybeSetEdidBlobsForConnectors(state); + UpdateConnectors(state); UpdateStateBesidesPlaneManager(state); return plane_manager_->Initialize(); } +void MockDrmDevice::UpdateConnectors(MockDrmState& state) { + UpdateConnectorsLinkStatus(state); + MaybeSetEdidBlobsForConnectors(state); +} + +void MockDrmDevice::UpdateConnectorsLinkStatus(MockDrmState& state) { + for (MockDrmDevice::ConnectorProperties& connector : + state.connector_properties) { + if (connector.connection && connector.modes.empty()) { + DrmWrapper::Property* connector_link_status = + FindObjectById(kLinkStatusPropId, connector.properties); + if (connector_link_status) { + connector_link_status->value = DRM_MODE_LINK_STATUS_BAD; + } + } + } +} + void MockDrmDevice::MaybeSetEdidBlobsForConnectors(MockDrmState& state) { for (auto& mock_connector : state.connector_properties) { const std::vector<uint8_t> edid_blob = mock_connector.edid_blob;
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.h b/ui/ozone/platform/drm/gpu/mock_drm_device.h index 24bdd475..513e936e 100644 --- a/ui/ozone/platform/drm/gpu/mock_drm_device.h +++ b/ui/ozone/platform/drm/gpu/mock_drm_device.h
@@ -237,6 +237,13 @@ void InitializeState(MockDrmState& state, bool use_atomic); bool InitializeStateWithResult(MockDrmState& state, bool use_atomic); + // Runs all connector update utility functions on |state|. + void UpdateConnectors(MockDrmState& state); + + // Update a connector's link status to bad if it has no modes (probably due + // to unsuccessful link-training. + void UpdateConnectorsLinkStatus(MockDrmState& state); + // Sets EDID blobs as property blobs so they can be fetched when needed via // GetPropertyBlob(). void MaybeSetEdidBlobsForConnectors(MockDrmState& state);
diff --git a/weblayer/browser/background_download_service_factory.cc b/weblayer/browser/background_download_service_factory.cc index 5c36cce2..9c833ac 100644 --- a/weblayer/browser/background_download_service_factory.cc +++ b/weblayer/browser/background_download_service_factory.cc
@@ -133,7 +133,8 @@ DependsOn(download::NavigationMonitorFactory::GetInstance()); } -KeyedService* BackgroundDownloadServiceFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +BackgroundDownloadServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { SimpleFactoryKey* key = ProfileImpl::FromBrowserContext(context) ->GetBrowserContext() @@ -152,11 +153,10 @@ SystemNetworkContextManager::GetInstance()->GetSharedURLLoaderFactory(); return download::BuildInMemoryDownloadService( - key, std::move(clients), content::GetNetworkConnectionTracker(), - base::FilePath(), - std::make_unique<DownloadBlobContextGetterFactory>(context), - io_task_runner, url_loader_factory) - .release(); + key, std::move(clients), content::GetNetworkConnectionTracker(), + base::FilePath(), + std::make_unique<DownloadBlobContextGetterFactory>(context), + io_task_runner, url_loader_factory); } // Build download service for a regular browsing context.
diff --git a/weblayer/browser/background_download_service_factory.h b/weblayer/browser/background_download_service_factory.h index 4e7c0be..364ce98c 100644 --- a/weblayer/browser/background_download_service_factory.h +++ b/weblayer/browser/background_download_service_factory.h
@@ -37,7 +37,7 @@ ~BackgroundDownloadServiceFactory() override = default; // BrowserContextKeyedService: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override;
diff --git a/weblayer/browser/verdict_cache_manager_factory.cc b/weblayer/browser/verdict_cache_manager_factory.cc index 8f4c321..14442cab 100644 --- a/weblayer/browser/verdict_cache_manager_factory.cc +++ b/weblayer/browser/verdict_cache_manager_factory.cc
@@ -33,10 +33,11 @@ DependsOn(HostContentSettingsMapFactory::GetInstance()); } -KeyedService* VerdictCacheManagerFactory::BuildServiceInstanceFor( +std::unique_ptr<KeyedService> +VerdictCacheManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { BrowserContextImpl* context_impl = static_cast<BrowserContextImpl*>(context); - return new safe_browsing::VerdictCacheManager( + return std::make_unique<safe_browsing::VerdictCacheManager>( /*history_service=*/nullptr, HostContentSettingsMapFactory::GetForBrowserContext(context), context_impl->pref_service(), /*sync_observer=*/nullptr);
diff --git a/weblayer/browser/verdict_cache_manager_factory.h b/weblayer/browser/verdict_cache_manager_factory.h index 69fabb7..153db13 100644 --- a/weblayer/browser/verdict_cache_manager_factory.h +++ b/weblayer/browser/verdict_cache_manager_factory.h
@@ -42,10 +42,10 @@ delete; // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; }; } // namespace weblayer -#endif // WEBLAYER_BROWSER_VERDICT_CACHE_MANAGER_FACTORY_H_ \ No newline at end of file +#endif // WEBLAYER_BROWSER_VERDICT_CACHE_MANAGER_FACTORY_H_