diff --git a/DEPS b/DEPS index 738651c..067bbadb 100644 --- a/DEPS +++ b/DEPS
@@ -304,19 +304,19 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '89742d768c973ea0e07676713825a105039b9a5d', + 'skia_revision': '51c838db272c8543f258bf5d5c6a84f4cf677676', # 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': 'e528f9f7a7367505aa70b3dba2190cf8468cb74c', + 'v8_revision': '67b838d1b1df5f9bf137cca57fea1e524dd5e756', # 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': '7d8cbb600e5ef9bc63d039bd422af8e5c3e2a281', + 'angle_revision': 'a0b0ec00baead8d24541b5f4279fe3568318cb8b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'd0aa9ad9447025a42f17df1b93bd71183e9b2d1f', + 'swiftshader_revision': 'ff8cc02ea659b8d64cf45f2cdd425ee293ddac03', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -331,7 +331,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:11.20221222.0.1', + 'fuchsia_version': 'version:11.20221222.1.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -375,7 +375,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'b10b1305cef856fefe0827de2a1ba20d52c0580a', + 'catapult_revision': 'ebbb83f192fe9ee3214119184001b9ddcfd44fb0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -383,7 +383,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': '37d35582c97bf3017430fb6e93e167911e64316e', + 'devtools_frontend_revision': 'a1a6fc838a1eee5579553a942f726585482c5cb3', # 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. @@ -419,7 +419,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': '906fc9df206d668191e9660a16688e27eb3d97ce', + 'dawn_revision': 'ffcd024aaac27858071fdd37ff6b979e9fb20253', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -463,7 +463,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libcxxabi_revision': 'df3cc8ecee393c765a7274a4687f8dff3558d590', + 'libcxxabi_revision': 'dc82f3042daa8b06d34e51d8492d37ce901a6f8d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -776,7 +776,7 @@ 'src/clank': { 'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' + - '3e0d5ccc185f18759008e2f588f33e31cdf52104', + 'c70b5dd91cb22039dab4a0272fa6169c4f2cb9ac', 'condition': 'checkout_android and checkout_src_internal', }, @@ -965,7 +965,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'XNQCcCxsa8Vznu546BS4QiWwlsCp1_1rV1J_5rSghKwC', + 'version': 'Q0RddCfn0BxFtUdiySojmUsDxQcuYrX4W1JRRHXk-30C', }, ], 'condition': 'checkout_android', @@ -1210,13 +1210,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cf31045b347e24e6619f2564fdb0c2490f661745', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0b96058844728db8040a7348cc4c61fde453401a', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'aefadfcacebbc1d64d8fd81f07a7dbf4bf12cec2', + 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'd3bfcd511b8a7d0d1250ae7b6a8c538691437c32', 'condition': 'checkout_src_internal', }, @@ -1900,7 +1900,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0eb5bc35c0153313afefab2a3b3e1b4196c6640a', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3d7e0ba34a931e67b9165cb4b54f037d0f04479d', 'condition': 'checkout_src_internal', },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index e5d93a18..74e6d0d 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1075,6 +1075,7 @@ "style/style_viewer/pill_button_instances_grid_view_factory.cc", "style/style_viewer/radio_button_group_instances_grid_view_factory.cc", "style/style_viewer/radio_button_instances_grid_view_factory.cc", + "style/style_viewer/system_text_instances_grid_view_factory.cc", "style/style_viewer/system_ui_components_grid_view.cc", "style/style_viewer/system_ui_components_grid_view.h", "style/style_viewer/system_ui_components_grid_view_factories.h", @@ -2058,6 +2059,10 @@ "wm/default_window_resizer.cc", "wm/default_window_resizer.h", "wm/desks/autotest_desks_api.cc", + "wm/desks/cros_next_desk_button.cc", + "wm/desks/cros_next_desk_button.h", + "wm/desks/cros_next_desk_button_base.cc", + "wm/desks/cros_next_desk_button_base.h", "wm/desks/desk.cc", "wm/desks/desk.h", "wm/desks/desk_action_context_menu.cc",
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc index 2b5dad4..0c6477d 100644 --- a/ash/accelerators/debug_commands.cc +++ b/ash/accelerators/debug_commands.cc
@@ -233,9 +233,10 @@ DCHECK(floated_window); - float_controller->OnFlingOrSwipeForTablet( - floated_window, - /*left=*/action == DEBUG_TUCK_FLOATED_WINDOW_LEFT, /*up=*/true); + const float velocity_x = + action == DEBUG_TUCK_FLOATED_WINDOW_LEFT ? -500.f : 500.f; + float_controller->OnFlingOrSwipeForTablet(floated_window, velocity_x, + /*velocity_y=*/0.f); } } // namespace
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc index 72664e5..bda31f6 100644 --- a/ash/constants/ash_pref_names.cc +++ b/ash/constants/ash_pref_names.cc
@@ -1171,6 +1171,11 @@ // An boolean pref that indicates whether portrait relighting is applied. const char kPortraitRelighting[] = "ash.camera.portrait_relighting"; +// Specifies if ARC app sync metrics should be recorded, i.e. this is the +// initial session after sync consent screen. +const char kRecordArcAppSyncMetrics[] = + "ash.should_record_arc_app_sync_metrics"; + // NOTE: New prefs should start with the "ash." prefix. Existing prefs moved // into this file should not be renamed, since they may be synced.
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index 058885d..b1eb935f 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -538,6 +538,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kPortraitRelighting[]; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kRecordArcAppSyncMetrics[]; + } // namespace prefs } // namespace ash
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc index 222feda..da54311 100644 --- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc +++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
@@ -820,6 +820,9 @@ "FastPair.SubsequentPairing.Initialization.RetriesBeforeSuccess"; constexpr char kInitializePairingProcessRetriesBeforeSuccessRetroactive[] = "FastPair.RetroactivePairing.Initialization.RetriesBeforeSuccess"; +const char kHandshakeEffectiveSuccessRate[] = + "FastPair.Handshake.EffectiveSuccessRate"; +const char kHandshakeAttemptCount[] = "FastPair.Handshake.AttemptCount"; const std::string GetEngagementFlowInitialModelIdMetric( const ash::quick_pair::Device& device) { @@ -1363,6 +1366,15 @@ initialization_step); } +void RecordEffectiveHandshakeSuccess(bool success) { + base::UmaHistogramBoolean(kHandshakeEffectiveSuccessRate, success); +} + +void RecordHandshakeAttemptCount(int num_attempts) { + base::UmaHistogramExactLinear(kHandshakeAttemptCount, num_attempts, + /*exclusive_max=*/10); +} + void RecordHandshakeResult(bool success) { base::UmaHistogramBoolean(kHandshakeResult, success); }
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h index 84f3c16b..e805bc55 100644 --- a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h +++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
@@ -381,6 +381,12 @@ FastPairGattConnectionSteps initialization_step); COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordEffectiveHandshakeSuccess(bool success); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordHandshakeAttemptCount(int num_attempts); + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) void RecordHandshakeResult(bool success); COMPONENT_EXPORT(QUICK_PAIR_COMMON)
diff --git a/ash/quick_pair/pairing/pairer_broker_impl.cc b/ash/quick_pair/pairing/pairer_broker_impl.cc index b22802f..fe1bff1 100644 --- a/ash/quick_pair/pairing/pairer_broker_impl.cc +++ b/ash/quick_pair/pairing/pairer_broker_impl.cc
@@ -27,6 +27,7 @@ namespace { constexpr int kMaxFailureRetryCount = 3; +constexpr int kMaxNumHandshakeAttempts = 3; // 1s delay after cancelling pairing was chosen to align with Android's Fast // Pair implementation. @@ -113,19 +114,26 @@ } void PairerBrokerImpl::CreateHandshake(scoped_refptr<Device> device) { - // TODO(b/259429032): Add 3 retries for this handshake. auto* fast_pair_handshake = FastPairHandshakeLookup::GetInstance()->Get(device); - if (fast_pair_handshake && fast_pair_handshake->completed_successfully()) { - QP_LOG(INFO) << __func__ - << ": Reusing existing handshake for pair attempt."; - RecordFastPairInitializePairingProcessEvent( - *device, FastPairInitializePairingProcessEvent::kHandshakeReused); - StartBondingAttempt(device); - return; + + if (fast_pair_handshake) { + if (fast_pair_handshake->completed_successfully()) { + QP_LOG(INFO) << __func__ + << ": Reusing existing handshake for pair attempt."; + RecordFastPairInitializePairingProcessEvent( + *device, FastPairInitializePairingProcessEvent::kHandshakeReused); + StartBondingAttempt(device); + return; + } else { + // If the previous handshake did not complete successfully, erase it + // before attempting to create a new handshake for the device. + FastPairHandshakeLookup::GetInstance()->Erase(device); + } } QP_LOG(INFO) << __func__ << ": Creating new handshake for pair attempt."; + num_handshake_attempts_[device->ble_address]++; FastPairHandshakeLookup::GetInstance()->Create( adapter_, device, base::BindOnce(&PairerBrokerImpl::OnHandshakeComplete, @@ -165,13 +173,27 @@ device->ble_address, true); } + RecordEffectiveHandshakeSuccess(/*success=*/true); + RecordHandshakeAttemptCount(num_handshake_attempts_[device->ble_address]); + + // Reset |num_handshake_attempts_| so if the handshake is lost during pairing, + // we will attempt to create it 3 more times. This should be an extremely rare + // situation, such as handshake happening directly before the device rotates + // ble addresses. + num_handshake_attempts_[device->ble_address] = 0; StartBondingAttempt(device); } void PairerBrokerImpl::OnHandshakeFailure(scoped_refptr<Device> device, PairFailure failure) { + if (num_handshake_attempts_[device->ble_address] < kMaxNumHandshakeAttempts) { + CreateHandshake(device); + return; + } + QP_LOG(INFO) << __func__ << ": Handshake failed to be created. Notifying observers."; + RecordEffectiveHandshakeSuccess(/*success=*/false); RecordInitializationFailureReason(*device, failure); for (auto& observer : observers_) { observer.OnPairFailure(device, failure);
diff --git a/ash/quick_pair/pairing/pairer_broker_impl.h b/ash/quick_pair/pairing/pairer_broker_impl.h index 0a645117..78ba9d4 100644 --- a/ash/quick_pair/pairing/pairer_broker_impl.h +++ b/ash/quick_pair/pairing/pairer_broker_impl.h
@@ -73,6 +73,7 @@ base::flat_map<std::string, int> pair_failure_counts_; base::flat_map<std::string, bool> did_handshake_previously_complete_successfully_map_; + base::flat_map<std::string, int> num_handshake_attempts_; scoped_refptr<device::BluetoothAdapter> adapter_; std::unique_ptr<FastPairUnpairHandler> fast_pair_unpair_handler_;
diff --git a/ash/quick_pair/pairing/pairer_broker_impl_unittest.cc b/ash/quick_pair/pairing/pairer_broker_impl_unittest.cc index 849c4e7..5292eee 100644 --- a/ash/quick_pair/pairing/pairer_broker_impl_unittest.cc +++ b/ash/quick_pair/pairing/pairer_broker_impl_unittest.cc
@@ -58,6 +58,9 @@ "FastPair.InitialPairing.Pairing"; constexpr char kProtocolPairingStepSubsequent[] = "FastPair.SubsequentPairing.Pairing"; +const char kHandshakeEffectiveSuccessRate[] = + "FastPair.Handshake.EffectiveSuccessRate"; +const char kHandshakeAttemptCount[] = "FastPair.Handshake.AttemptCount"; class FakeFastPairPairer : public ash::quick_pair::FastPairPairer { public: @@ -700,11 +703,88 @@ 1); } -TEST_F(PairerBrokerImplTest, NoPairingIfHandshakeFailed_Initial) { +TEST_F(PairerBrokerImplTest, PairAfterTwoHandshakeFailures_Initial) { + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 0); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 0); + CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, /*protocol=*/Protocol::kFastPairInitial); pairer_broker_->PairDevice(device_); fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(); + EXPECT_TRUE(pairer_broker_->IsPairing()); + + fast_pair_pairer_factory_->fake_fast_pair_pairer()->TriggerPairedCallback(); + + EXPECT_EQ(device_paired_count_, 1); + EXPECT_EQ(pair_failure_count_, 0); + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 1); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 1); + + fast_pair_pairer_factory_->fake_fast_pair_pairer() + ->TriggerPairingProcedureCompleteCallback(); + EXPECT_FALSE(pairer_broker_->IsPairing()); +} + +TEST_F(PairerBrokerImplTest, PairAfterTwoHandshakeFailures_Subsequent) { + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 0); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 0); + + CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, + /*protocol=*/Protocol::kFastPairSubsequent); + pairer_broker_->PairDevice(device_); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(); + EXPECT_TRUE(pairer_broker_->IsPairing()); + + fast_pair_pairer_factory_->fake_fast_pair_pairer()->TriggerPairedCallback(); + + EXPECT_EQ(device_paired_count_, 1); + EXPECT_EQ(pair_failure_count_, 0); + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 1); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 1); + + fast_pair_pairer_factory_->fake_fast_pair_pairer() + ->TriggerPairingProcedureCompleteCallback(); + EXPECT_FALSE(pairer_broker_->IsPairing()); +} + +TEST_F(PairerBrokerImplTest, PairAfterTwoHandshakeFailures_Retroactive) { + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 0); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 0); + + CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, + /*protocol=*/Protocol::kFastPairRetroactive); + pairer_broker_->PairDevice(device_); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(); + EXPECT_TRUE(pairer_broker_->IsPairing()); + + fast_pair_pairer_factory_->fake_fast_pair_pairer()->TriggerPairedCallback(); + + EXPECT_EQ(device_paired_count_, 1); + EXPECT_EQ(pair_failure_count_, 0); + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 1); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 1); + + fast_pair_pairer_factory_->fake_fast_pair_pairer() + ->TriggerPairingProcedureCompleteCallback(); + EXPECT_FALSE(pairer_broker_->IsPairing()); +} + +TEST_F(PairerBrokerImplTest, NoPairingIfHandshakeFailed_Initial) { + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 0); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 0); + + CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, + /*protocol=*/Protocol::kFastPairInitial); + pairer_broker_->PairDevice(device_); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); EXPECT_FALSE(pairer_broker_->IsPairing()); EXPECT_EQ(device_paired_count_, 0); @@ -713,13 +793,19 @@ kInitializePairingProcessFailureReasonInitial, PairFailure::kCreateGattConnection), 1); + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 1); } TEST_F(PairerBrokerImplTest, NoPairingIfHandshakeFailed_Subsequent) { + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 0); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 0); + CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, /*protocol=*/Protocol::kFastPairSubsequent); pairer_broker_->PairDevice(device_); fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); EXPECT_FALSE(pairer_broker_->IsPairing()); EXPECT_EQ(device_paired_count_, 0); @@ -728,13 +814,19 @@ kInitializePairingProcessFailureReasonSubsequent, PairFailure::kCreateGattConnection), 1); + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 1); } TEST_F(PairerBrokerImplTest, NoPairingIfHandshakeFailed_Retroactive) { + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 0); + histogram_tester_.ExpectTotalCount(kHandshakeAttemptCount, 0); + CreateMockDevice(DeviceFastPairVersion::kHigherThanV1, /*protocol=*/Protocol::kFastPairRetroactive); pairer_broker_->PairDevice(device_); fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); + fake_fast_pair_handshake_->InvokeCallback(PairFailure::kCreateGattConnection); EXPECT_FALSE(pairer_broker_->IsPairing()); EXPECT_EQ(device_paired_count_, 0); @@ -743,6 +835,7 @@ kInitializePairingProcessFailureReasonRetroactive, PairFailure::kCreateGattConnection), 1); + histogram_tester_.ExpectTotalCount(kHandshakeEffectiveSuccessRate, 1); } } // namespace quick_pair } // namespace ash
diff --git a/ash/style/ash_color_mixer.cc b/ash/style/ash_color_mixer.cc index dad978d..92ba2bb 100644 --- a/ash/style/ash_color_mixer.cc +++ b/ash/style/ash_color_mixer.cc
@@ -5,7 +5,6 @@ #include "ash/style/ash_color_mixer.h" #include "ash/constants/ash_features.h" -#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_id.h" #include "ash/style/dark_light_mode_controller_impl.h" #include "ash/style/harmonized_colors.h" @@ -63,9 +62,7 @@ } const bool use_dark_color = - features::IsDarkLightModeEnabled() - ? key.color_mode == ui::ColorProviderManager::ColorMode::kDark - : DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(); + key.color_mode == ui::ColorProviderManager::ColorMode::kDark; // Colors of the Shield and Base layers. const SkColor default_background_color = @@ -103,9 +100,7 @@ void AddControlsColors(ui::ColorMixer& mixer, const ui::ColorProviderManager::Key& key) { const bool use_dark_color = - features::IsDarkLightModeEnabled() - ? key.color_mode == ui::ColorProviderManager::ColorMode::kDark - : DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(); + key.color_mode == ui::ColorProviderManager::ColorMode::kDark; // ControlsLayer colors mixer[kColorAshHairlineBorderColor] = @@ -128,9 +123,7 @@ void AddContentColors(ui::ColorMixer& mixer, const ui::ColorProviderManager::Key& key) { const bool use_dark_color = - features::IsDarkLightModeEnabled() - ? key.color_mode == ui::ColorProviderManager::ColorMode::kDark - : DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(); + key.color_mode == ui::ColorProviderManager::ColorMode::kDark; // ContentLayer colors. mixer[kColorAshScrollBarColor] = @@ -172,12 +165,9 @@ ui::SetAlpha(kColorAshAppStateIndicatorColor, kDisabledColorOpacity); mixer[kColorAshShelfHandleColor] = {cros_tokens::kIconColorSecondary}; mixer[kColorAshShelfTooltipBackgroundColor] = { - features::IsDarkLightModeEnabled() ? kColorAshInvertedShieldAndBase80 - : kColorAshShieldAndBase80}; + kColorAshInvertedShieldAndBase80}; mixer[kColorAshShelfTooltipForegroundColor] = { - features::IsDarkLightModeEnabled() - ? cros_tokens::kTextColorPrimaryInverted - : cros_tokens::kTextColorPrimary}; + cros_tokens::kTextColorPrimaryInverted}; mixer[kColorAshSliderColorActive] = {kColorAshTextColorURL}; mixer[kColorAshSliderColorInactive] = {kColorAshScrollBarColor}; mixer[kColorAshRadioColorActive] = {kColorAshTextColorURL}; @@ -384,11 +374,7 @@ void AddCrosStylesColorMixer(ui::ColorProvider* provider, const ui::ColorProviderManager::Key& key) { ui::ColorMixer& mixer = provider->AddMixer(); - bool dark_mode = - features::IsDarkLightModeEnabled() - ? key.color_mode == ui::ColorProviderManager::ColorMode::kDark - : DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(); - + bool dark_mode = key.color_mode == ui::ColorProviderManager::ColorMode::kDark; if (ash::features::IsJellyEnabled()) { AddRefPalette(mixer, key); } else { @@ -409,9 +395,7 @@ const ui::ColorProviderManager::Key& key) { ui::ColorMixer& mixer = provider->AddMixer(); const bool use_dark_color = - features::IsDarkLightModeEnabled() - ? key.color_mode == ui::ColorProviderManager::ColorMode::kDark - : DarkLightModeControllerImpl::Get()->IsDarkModeEnabled(); + key.color_mode == ui::ColorProviderManager::ColorMode::kDark; AddShieldAndBaseColors(mixer, key); AddControlsColors(mixer, key); @@ -452,19 +436,6 @@ mixer[ui::kColorAshOnboardingFocusRing] = {cros_tokens::kColorProminentDark}; - if (!features::IsDarkLightModeEnabled()) { - ash::ScopedLightModeAsDefault scoped_light_mode_as_default; - mixer[ui::kColorAshSystemUILightBorderColor1] = { - ui::kColorHighlightBorderBorder1}; - mixer[ui::kColorAshSystemUILightBorderColor2] = { - ui::kColorHighlightBorderBorder2}; - mixer[ui::kColorAshSystemUILightHighlightColor1] = { - ui::kColorHighlightBorderHighlight1}; - mixer[ui::kColorAshSystemUILightHighlightColor2] = { - ui::kColorHighlightBorderHighlight2}; - return; - } - mixer[ui::kColorAshSystemUIMenuBackground] = {kColorAshShieldAndBase80}; mixer[ui::kColorAshSystemUIMenuIcon] = {kColorAshIconColorPrimary}; mixer[ui::kColorAshSystemUIMenuItemBackgroundSelected] = {kColorAshInkDrop};
diff --git a/ash/style/pill_button.cc b/ash/style/pill_button.cc index 7314727..1ff9b8f 100644 --- a/ash/style/pill_button.cc +++ b/ash/style/pill_button.cc
@@ -5,7 +5,6 @@ #include "ash/style/pill_button.h" #include "ash/constants/ash_features.h" -#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_id.h" #include "ash/style/color_util.h" #include "ash/style/style_util.h"
diff --git a/ash/style/style_viewer/system_text_instances_grid_view_factory.cc b/ash/style/style_viewer/system_text_instances_grid_view_factory.cc new file mode 100644 index 0000000..fbf0d853 --- /dev/null +++ b/ash/style/style_viewer/system_text_instances_grid_view_factory.cc
@@ -0,0 +1,89 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/style/style_viewer/system_ui_components_grid_view_factories.h" + +#include "ash/style/style_viewer/system_ui_components_grid_view.h" +#include "ash/style/system_textfield.h" +#include "ash/style/system_textfield_controller.h" + +namespace ash { + +namespace { + +// Configurations of grid view for `SystemTextfield` instances. +constexpr size_t kGridViewRowNum = 4; +constexpr size_t kGridViewColNum = 1; +constexpr size_t kGridViewRowGroupSize = 4; +constexpr size_t kGirdViewColGroupSize = 1; + +} // namespace + +// A component grid view class which allows to add a system textfield with +// system textfield controller. It manages the unique pointers of textfield +// controller. +class TextfieldGridView : public SystemUIComponentsGridView { + public: + TextfieldGridView() + : SystemUIComponentsGridView(kGridViewRowNum, + kGridViewColNum, + kGridViewRowGroupSize, + kGirdViewColGroupSize) {} + TextfieldGridView(const TextfieldGridView&) = delete; + TextfieldGridView& operator=(const TextfieldGridView&) = delete; + ~TextfieldGridView() override = default; + + // Adds a textfield with `SystemTextController` as its controller. + void AddTextfieldWithController(const std::u16string& name, + std::unique_ptr<SystemTextfield> textfield) { + controllers_.emplace_back( + std::make_unique<SystemTextfieldController>(textfield.get())); + AddInstance(name, std::move(textfield)); + } + + private: + std::vector<std::unique_ptr<SystemTextfieldController>> controllers_; +}; + +std::unique_ptr<SystemUIComponentsGridView> +CreateSystemTextfieldInstancesGridView() { + auto grid_view = std::make_unique<TextfieldGridView>(); + + // Small size textfield. + auto textfield_small = + std::make_unique<SystemTextfield>(SystemTextfield::Type::kSmall); + textfield_small->SetAccessibleName(u"Small Text"); + textfield_small->SetPlaceholderText(u"Small Text"); + + // Medium size textfield. + auto textfield_medium = + std::make_unique<SystemTextfield>(SystemTextfield::Type::kMedium); + textfield_medium->SetAccessibleName(u"Medium Text"); + textfield_medium->SetPlaceholderText(u"Medium Text"); + + // Large size textfield. + auto textfield_large = + std::make_unique<SystemTextfield>(SystemTextfield::Type::kLarge); + textfield_large->SetAccessibleName(u"Large Text"); + textfield_large->SetPlaceholderText(u"Large Text"); + + // Disabled textfield. + auto textfield_disabled = + std::make_unique<SystemTextfield>(SystemTextfield::Type::kMedium); + textfield_disabled->SetAccessibleName(u"Disabled Text"); + textfield_disabled->SetPlaceholderText(u"Disable Text"); + textfield_disabled->SetEnabled(false); + + grid_view->AddTextfieldWithController(u"Textfield Small", + std::move(textfield_small)); + grid_view->AddTextfieldWithController(u"Textfield Medium", + std::move(textfield_medium)); + grid_view->AddTextfieldWithController(u"Textfield Large", + std::move(textfield_large)); + grid_view->AddTextfieldWithController(u"Textfield Disabled", + std::move(textfield_disabled)); + return grid_view; +} + +} // namespace ash
diff --git a/ash/style/style_viewer/system_ui_components_grid_view_factories.h b/ash/style/style_viewer/system_ui_components_grid_view_factories.h index e20e5fd6..66cf6f7 100644 --- a/ash/style/style_viewer/system_ui_components_grid_view_factories.h +++ b/ash/style/style_viewer/system_ui_components_grid_view_factories.h
@@ -25,6 +25,8 @@ CreateRadioButtonGroupInstancesGridView(); std::unique_ptr<SystemUIComponentsGridView> CreateKnobSwitchInstancesGridView(); std::unique_ptr<SystemUIComponentsGridView> CreateTabSliderInstancesGridView(); +std::unique_ptr<SystemUIComponentsGridView> +CreateSystemTextfieldInstancesGridView(); } // namespace ash
diff --git a/ash/style/style_viewer/system_ui_components_style_viewer_view.cc b/ash/style/style_viewer/system_ui_components_style_viewer_view.cc index 0efd46e..cc825f7 100644 --- a/ash/style/style_viewer/system_ui_components_style_viewer_view.cc +++ b/ash/style/style_viewer/system_ui_components_style_viewer_view.cc
@@ -169,6 +169,9 @@ u"KnobSwitch", base::BindRepeating(&CreateKnobSwitchInstancesGridView)); viewer_view->AddComponent( u"TabSlider", base::BindRepeating(&CreateTabSliderInstancesGridView)); + viewer_view->AddComponent( + u"System Textfield", + base::BindRepeating(&CreateSystemTextfieldInstancesGridView)); // Show PillButton on start. viewer_view->ShowComponentInstances(u"PillButton");
diff --git a/ash/style/system_textfield.cc b/ash/style/system_textfield.cc index 1f99590..945b3ea9 100644 --- a/ash/style/system_textfield.cc +++ b/ash/style/system_textfield.cc
@@ -93,8 +93,9 @@ SystemTextfield::~SystemTextfield() = default; void SystemTextfield::SetActive(bool active) { - if (active_ == active) + if (active_ == active) { return; + } active_ = active; @@ -180,8 +181,9 @@ } void SystemTextfield::UpdateTextColor() { - if (!GetWidget()) + if (!GetWidget()) { return; + } // Set text color. auto* color_provider = GetColorProvider();
diff --git a/ash/style/system_textfield_controller.cc b/ash/style/system_textfield_controller.cc index 4b239d4..cb6d2d6 100644 --- a/ash/style/system_textfield_controller.cc +++ b/ash/style/system_textfield_controller.cc
@@ -35,8 +35,9 @@ const ui::KeyEvent& key_event) { DCHECK_EQ(textfield_, sender); - if (key_event.type() != ui::ET_KEY_PRESSED) + if (key_event.type() != ui::ET_KEY_PRESSED) { return false; + } const bool active = textfield_->active(); if (key_event.key_code() == ui::VKEY_RETURN) { @@ -90,8 +91,9 @@ // When selecting all text was deferred, do it if there is no selection. if (defer_select_all_) { defer_select_all_ = false; - if (!textfield_->HasSelection()) + if (!textfield_->HasSelection()) { textfield_->SelectAll(false); + } return true; } break;
diff --git a/ash/system/network/network_list_network_item_view.cc b/ash/system/network/network_list_network_item_view.cc index d97ff04..70252ec 100644 --- a/ash/system/network/network_list_network_item_view.cc +++ b/ash/system/network/network_list_network_item_view.cc
@@ -93,20 +93,6 @@ return ActivationStateType::kUnknown; } -bool IsNetworkInhibited(const NetworkStatePropertiesPtr& network_properties) { - if (!NetworkTypeMatchesType(network_properties->type, - NetworkType::kCellular)) { - return false; - } - - const chromeos::network_config::mojom::DeviceStateProperties* - cellular_device = - Shell::Get()->system_tray_model()->network_state_model()->GetDevice( - NetworkType::kCellular); - - return cellular_device && IsInhibited(cellular_device); -} - bool IsCellularNetworkSimLocked( const NetworkStatePropertiesPtr& network_properties) { DCHECK( @@ -157,35 +143,6 @@ return false; } -bool IsNetworkDisabled(const NetworkStatePropertiesPtr& network_properties) { - if (network_properties->prohibited_by_policy) { - return true; - } - - if (!NetworkTypeMatchesType(network_properties->type, - NetworkType::kCellular)) { - return false; - } - - const CellularStateProperties* cellular = - network_properties->type_state->get_cellular().get(); - - if (!Shell::Get()->session_controller()->IsActiveUserSessionStarted() && - cellular->sim_locked) { - return true; - } - - if (cellular->activation_state == ActivationStateType::kActivating) { - return true; - } - - if (IsNetworkInhibited(network_properties)) { - return true; - } - - return false; -} - bool IsWifiNetworkSecured(const NetworkStatePropertiesPtr& network_properties) { DCHECK(NetworkTypeMatchesType(network_properties->type, NetworkType::kWiFi)); return network_properties->type_state->get_wifi()->security != @@ -291,7 +248,6 @@ if (IsNetworkDisabled(network_properties)) { UpdateDisabledTextColor(); - SetEnabled(false); } if (network_properties_->prohibited_by_policy) {
diff --git a/ash/system/network/network_list_network_item_view_unittest.cc b/ash/system/network/network_list_network_item_view_unittest.cc index a538f9b..a2282999e 100644 --- a/ash/system/network/network_list_network_item_view_unittest.cc +++ b/ash/system/network/network_list_network_item_view_unittest.cc
@@ -385,11 +385,6 @@ wifi_network->prohibited_by_policy = true; UpdateViewForNetwork(wifi_network); - // When prohibited by policy network row is not clickable. - EXPECT_FALSE(LastClickedNetworkListItem()); - LeftClickOn(network_list_network_item_view()); - EXPECT_FALSE(LastClickedNetworkListItem()); - ASSERT_TRUE(network_list_network_item_view()->right_view()); EXPECT_TRUE(network_list_network_item_view()->right_view()->GetVisible()); ASSERT_TRUE(views::IsViewClass<views::ImageView>(
diff --git a/ash/system/network/network_list_view_controller_impl.cc b/ash/system/network/network_list_view_controller_impl.cc index d50f8a22..2acd231 100644 --- a/ash/system/network/network_list_view_controller_impl.cc +++ b/ash/system/network/network_list_view_controller_impl.cc
@@ -818,6 +818,7 @@ network_view->UpdateViewForNetwork(network); network_detailed_network_view()->GetNetworkList(type)->ReorderChildView( network_view, index); + network_view->SetEnabled(!IsNetworkDisabled(network)); // Only emit ethernet metric each time we show Ethernet section // for the first time. We use `has_reordered_a_network` to determine
diff --git a/ash/system/network/network_list_view_controller_unittest.cc b/ash/system/network/network_list_view_controller_unittest.cc index e5d6780..e0ef9cb 100644 --- a/ash/system/network/network_list_view_controller_unittest.cc +++ b/ash/system/network/network_list_view_controller_unittest.cc
@@ -427,6 +427,17 @@ } } + bool GetNetworkListItemIsEnabled(NetworkType type, size_t index) { + EXPECT_STREQ(network_list(type)->children().at(index)->GetClassName(), + kNetworkListNetworkItemView); + + NetworkListNetworkItemView* network = + static_cast<NetworkListNetworkItemView*>( + network_list(type)->children().at(index)); + + return network->GetEnabled(); + } + void SetBluetoothAdapterState(BluetoothSystemState system_state) { bluetooth_config_test_helper() ->fake_adapter_state_controller() @@ -1256,4 +1267,48 @@ cros_network()->GetScanCount(NetworkType::kTether)); } +TEST_P(NetworkListViewControllerTest, NetworkItemIsEnabled) { + auto properties = + chromeos::network_config::mojom::DeviceStateProperties::New(); + properties->type = NetworkType::kCellular; + properties->device_state = DeviceStateType::kEnabled; + properties->sim_infos = CellularSIMInfos(kCellularTestIccid, kTestBaseEid); + + cros_network()->SetDeviceProperties(properties.Clone()); + ASSERT_THAT(GetMobileSubHeader(), NotNull()); + EXPECT_TRUE(GetAddEsimButton()->GetEnabled()); + + cros_network()->AddNetworkAndDevice( + CrosNetworkConfigTestHelper::CreateStandaloneNetworkProperties( + kCellularName, NetworkType::kCellular, + ConnectionStateType::kConnected)); + + if (IsQsRevampEnabled()) { + CheckNetworkListItem(NetworkType::kCellular, /*index=*/0u, kCellularName); + EXPECT_TRUE(GetNetworkListItemIsEnabled(NetworkType::kCellular, 0u)); + } else { + CheckNetworkListItem(NetworkType::kCellular, /*index=*/1u, kCellularName); + EXPECT_TRUE(GetNetworkListItemIsEnabled(NetworkType::kCellular, 1u)); + } + + // Inhibit cellular device. + properties->inhibit_reason = InhibitReason::kResettingEuiccMemory; + cros_network()->SetDeviceProperties(properties.Clone()); + + if (IsQsRevampEnabled()) { + EXPECT_FALSE(GetNetworkListItemIsEnabled(NetworkType::kCellular, 0u)); + } else { + EXPECT_FALSE(GetNetworkListItemIsEnabled(NetworkType::kCellular, 1u)); + } + + // Uninhibit the device. + properties->inhibit_reason = InhibitReason::kNotInhibited; + cros_network()->SetDeviceProperties(properties.Clone()); + if (IsQsRevampEnabled()) { + EXPECT_TRUE(GetNetworkListItemIsEnabled(NetworkType::kCellular, 0u)); + } else { + EXPECT_TRUE(GetNetworkListItemIsEnabled(NetworkType::kCellular, 1u)); + } +} + } // namespace ash
diff --git a/ash/system/network/network_utils.cc b/ash/system/network/network_utils.cc index 998eb6e..66675f8 100644 --- a/ash/system/network/network_utils.cc +++ b/ash/system/network/network_utils.cc
@@ -5,9 +5,14 @@ #include "ash/system/network/network_utils.h" #include "ash/constants/ash_features.h" +#include "ash/session/session_controller_impl.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/system/model/system_tray_model.h" +#include "ash/system/network/tray_network_state_model.h" #include "base/metrics/histogram_functions.h" #include "base/strings/strcat.h" +#include "chromeos/services/network_config/public/cpp/cros_network_config_util.h" #include "ui/base/l10n/l10n_util.h" namespace ash { @@ -83,4 +88,55 @@ } } +bool IsNetworkDisabled( + const chromeos::network_config::mojom::NetworkStatePropertiesPtr& + network_properties) { + if (network_properties->prohibited_by_policy) { + return true; + } + + if (!chromeos::network_config::NetworkTypeMatchesType( + network_properties->type, + chromeos::network_config::mojom::NetworkType::kCellular)) { + return false; + } + + const chromeos::network_config::mojom::CellularStateProperties* cellular = + network_properties->type_state->get_cellular().get(); + + if (!Shell::Get()->session_controller()->IsActiveUserSessionStarted() && + cellular->sim_locked) { + return true; + } + + if (cellular->activation_state == + chromeos::network_config::mojom::ActivationStateType::kActivating) { + return true; + } + + if (IsNetworkInhibited(network_properties)) { + return true; + } + + return false; +} + +bool IsNetworkInhibited( + const chromeos::network_config::mojom::NetworkStatePropertiesPtr& + network_properties) { + if (!chromeos::network_config::NetworkTypeMatchesType( + network_properties->type, + chromeos::network_config::mojom::NetworkType::kCellular)) { + return false; + } + + const chromeos::network_config::mojom::DeviceStateProperties* + cellular_device = + Shell::Get()->system_tray_model()->network_state_model()->GetDevice( + chromeos::network_config::mojom::NetworkType::kCellular); + + return cellular_device && + chromeos::network_config::IsInhibited(cellular_device); +} + } // namespace ash
diff --git a/ash/system/network/network_utils.h b/ash/system/network/network_utils.h index 8d8c795..56ab0cb5d 100644 --- a/ash/system/network/network_utils.h +++ b/ash/system/network/network_utils.h
@@ -46,6 +46,16 @@ ASH_EXPORT absl::optional<std::u16string> GetPortalStateSubtext( const chromeos::network_config::mojom::PortalState& portal_state); +// Returns true if current network row is disabled. +ASH_EXPORT bool IsNetworkDisabled( + const chromeos::network_config::mojom::NetworkStatePropertiesPtr& + network_properties); + +// Returns true if current network is a cellular network and is inhibited. +ASH_EXPORT bool IsNetworkInhibited( + const chromeos::network_config::mojom::NetworkStatePropertiesPtr& + network_properties); + } // namespace ash #endif // ASH_SYSTEM_NETWORK_NETWORK_UTILS_H_
diff --git a/ash/system/phonehub/phone_hub_tray.cc b/ash/system/phonehub/phone_hub_tray.cc index a0af5d8..b8fdff9 100644 --- a/ash/system/phonehub/phone_hub_tray.cc +++ b/ash/system/phonehub/phone_hub_tray.cc
@@ -371,6 +371,12 @@ phone_status_view_dont_use_ = nullptr; } + if (features::IsEcheSWAEnabled() && features::IsEcheLauncherEnabled() && + phone_hub_manager_->GetAppStreamLauncherDataModel()) { + phone_hub_manager_->GetAppStreamLauncherDataModel() + ->SetShouldShowMiniLauncher(false); + } + bubble_.reset(); SetIsActive(false); shelf()->UpdateAutoHideState();
diff --git a/ash/system/phonehub/phone_hub_tray_unittest.cc b/ash/system/phonehub/phone_hub_tray_unittest.cc index f574254..c7096f29 100644 --- a/ash/system/phonehub/phone_hub_tray_unittest.cc +++ b/ash/system/phonehub/phone_hub_tray_unittest.cc
@@ -97,6 +97,10 @@ return phone_hub_manager_.fake_onboarding_ui_tracker(); } + phonehub::AppStreamLauncherDataModel* GetAppStreamLauncherDataModel() { + return phone_hub_manager_.fake_app_stream_launcher_data_model(); + } + void PressReturnKeyOnTrayButton() { const ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE); @@ -614,6 +618,34 @@ EXPECT_FALSE(GetOnboardingUiTracker()->ShouldShowOnboardingUi()); } +TEST_F(PhoneHubTrayTest, ShouldNotShowMiniLauncherOnCloseBubble) { + GetFeatureStatusProvider()->SetStatus( + phonehub::FeatureStatus::kEnabledAndConnected); + + ClickTrayButton(); + EXPECT_TRUE(phone_hub_tray_->is_active()); + + // Simulate showing the app stream mini launcher + GetAppStreamLauncherDataModel()->SetShouldShowMiniLauncher(true); + EXPECT_TRUE(GetAppStreamLauncherDataModel()->GetShouldShowMiniLauncher()); + + // Simulate a click outside the bubble. + phone_hub_tray_->ClickedOutsideBubble(); + + // Clicking outside should dismiss the bubble and should not show the app + // stream mini launcher. + EXPECT_FALSE(phone_hub_tray_->GetBubbleView()); + EXPECT_TRUE(phone_hub_tray_->GetVisible()); + EXPECT_FALSE(GetAppStreamLauncherDataModel()->GetShouldShowMiniLauncher()); + + // Opening the bubble again should still have the app stream mini launcher + // not shown. + ClickTrayButton(); + EXPECT_TRUE(phone_hub_tray_->GetBubbleView()); + EXPECT_TRUE(phone_hub_tray_->GetVisible()); + EXPECT_FALSE(GetAppStreamLauncherDataModel()->GetShouldShowMiniLauncher()); +} + TEST_F(PhoneHubTrayTest, ClickButtonsOnDisconnectedView) { // Simulates a phone disconnected error state to show the disconnected view. GetFeatureStatusProvider()->SetStatus(
diff --git a/ash/system/screen_layout_observer.cc b/ash/system/screen_layout_observer.cc index 0d9b957..e3a77d6 100644 --- a/ash/system/screen_layout_observer.cc +++ b/ash/system/screen_layout_observer.cc
@@ -8,7 +8,6 @@ #include <utility> #include <vector> -#include "ash/constants/ash_features.h" #include "ash/constants/notifier_catalogs.h" #include "ash/display/screen_orientation_controller.h" #include "ash/public/cpp/notification_utils.h"
diff --git a/ash/system/screen_layout_observer_unittest.cc b/ash/system/screen_layout_observer_unittest.cc index cb142d4..0a61e81 100644 --- a/ash/system/screen_layout_observer_unittest.cc +++ b/ash/system/screen_layout_observer_unittest.cc
@@ -6,7 +6,6 @@ #include <string> -#include "ash/constants/ash_features.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/test/ash_test_base.h" @@ -16,7 +15,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/devicetype_utils.h" @@ -63,8 +61,6 @@ bool IsNotificationShown() const; - base::test::ScopedFeatureList scoped_feature_list_; - private: const message_center::Notification* GetDisplayNotification() const; }; @@ -260,8 +256,6 @@ } TEST_F(ScreenLayoutObserverTest, DisplayNotificationsDisabled) { - scoped_feature_list_.Reset(); - UpdateDisplay("500x400"); display::SetInternalDisplayIds({display_manager()->first_display_id()}); EXPECT_TRUE(GetDisplayNotificationText().empty());
diff --git a/ash/system/time/calendar_event_list_view.cc b/ash/system/time/calendar_event_list_view.cc index 4543953..a4500e9 100644 --- a/ash/system/time/calendar_event_list_view.cc +++ b/ash/system/time/calendar_event_list_view.cc
@@ -47,11 +47,8 @@ constexpr auto kContentInsets = gfx::Insets::TLBR(0, 0, 20, 0); constexpr auto kContentInsetsJelly = gfx::Insets::TLBR(0, 16, 20, 16); -// The insets for `CalendarEmptyEventListView` label. -constexpr auto kOpenGoogleCalendarInsets = gfx::Insets::VH(6, 16); - // The insets for `CalendarEmptyEventListView`. -constexpr auto kOpenGoogleCalendarContainerInsets = gfx::Insets::VH(20, 80); +constexpr auto kOpenGoogleCalendarContainerInsets = gfx::Insets::VH(20, 60); // Border thickness for `CalendarEmptyEventListView`. constexpr int kOpenGoogleCalendarBorderThickness = 1; @@ -87,7 +84,6 @@ /*icon=*/nullptr), controller_(controller) { SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER); - label()->SetBorder(views::CreateEmptyBorder(kOpenGoogleCalendarInsets)); label()->SetTextContext(CONTEXT_CALENDAR_DATE); SetBorder(views::CreateRoundedRectBorder( kOpenGoogleCalendarBorderThickness, GetPreferredSize().height() / 2,
diff --git a/ash/webui/common/resources/network/apn_list.d.ts b/ash/webui/common/resources/network/apn_list.d.ts index 983fe59..93b4d72 100644 --- a/ash/webui/common/resources/network/apn_list.d.ts +++ b/ash/webui/common/resources/network/apn_list.d.ts
@@ -2,4 +2,42 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -export {}; +import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {ManagedCellularProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; + +export class ApnList extends PolymerElement { + static get is(): string; + static get template(): HTMLTemplateElement; + static get properties(): { + guid: StringConstructor, + managedCellularProperties: ManagedCellularProperties, + shouldOmitLinks: { + type: BooleanConstructor, + value: boolean, + }, + shouldShowApnDetailDialog_: { + type: BooleanConstructor, + value: boolean, + }, + isConnectedApnAutoDetected_: { + type: BooleanConstructor, + value: boolean, + }, + }; + openApnDetailDialogInCreateMode(): void; + private getApns_; + private isConnectedApnAutoDetected_: boolean; + private isApnConnected_; + private isApnAutoDetected_; + private onLearnMoreClicked_; + private onShowApnDetailDialog_; + private showApnDetailDialog_; + private shouldShowApnDetailDialog_: boolean; + private onApnDetailDialogClose_; +} + +declare global { + interface HTMLElementTagNameMap { + 'apn-list': ApnList; + } +}
diff --git a/ash/webui/diagnostics_ui/resources/.eslintrc.js b/ash/webui/diagnostics_ui/resources/.eslintrc.js new file mode 100644 index 0000000..4d830da --- /dev/null +++ b/ash/webui/diagnostics_ui/resources/.eslintrc.js
@@ -0,0 +1,35 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Disable clang-format because it produces odd formatting. +// clang-format off +module.exports = { + 'parserOptions': { + 'project': ['./tsconfig_base.json'], + }, + 'rules': { + '@typescript-eslint/explicit-function-return-type': ['error'], + }, + 'overrides': [{ + 'files': ['**/*.ts'], + 'parser': + '../../../../third_party/node/node_modules/@typescript-eslint/parser', + 'parserOptions': { + tsconfigRootDir: __dirname, + }, + 'plugins': ['@typescript-eslint'], + 'rules': { + '@typescript-eslint/naming-convention': + ['warn', + { + selector: ['classMethod', 'classProperty'], + format: ['camelCase'], + modifiers: ['private'], + trailingUnderscore: 'forbid', + }, + ], + }, + }], + }; +// clang-format on \ No newline at end of file
diff --git a/ash/webui/diagnostics_ui/resources/battery_status_card.ts b/ash/webui/diagnostics_ui/resources/battery_status_card.ts index d8a4a14..8a41d62 100644 --- a/ash/webui/diagnostics_ui/resources/battery_status_card.ts +++ b/ash/webui/diagnostics_ui/resources/battery_status_card.ts
@@ -15,6 +15,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './battery_status_card.html.js'; @@ -51,15 +52,15 @@ const BatteryStatusCardElementBase = I18nMixin(PolymerElement); export class BatteryStatusCardElement extends BatteryStatusCardElementBase { - static get is() { + static get is(): string { return 'battery-status-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { batteryChargeStatus_: { type: Object, @@ -133,7 +134,7 @@ this.observeBatteryHealth_(); } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); if (this.batteryChargeStatusObserverReceiver_) {
diff --git a/ash/webui/diagnostics_ui/resources/cellular_info.ts b/ash/webui/diagnostics_ui/resources/cellular_info.ts index 08d498e..4023da79 100644 --- a/ash/webui/diagnostics_ui/resources/cellular_info.ts +++ b/ash/webui/diagnostics_ui/resources/cellular_info.ts
@@ -7,6 +7,7 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './cellular_info.html.js'; @@ -22,15 +23,15 @@ const CellularInfoElementBase = I18nMixin(PolymerElement); export class CellularInfoElement extends CellularInfoElementBase { - static get is() { + static get is(): string { return 'cellular-info'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { network: { type: Object,
diff --git a/ash/webui/diagnostics_ui/resources/connectivity_card.ts b/ash/webui/diagnostics_ui/resources/connectivity_card.ts index acf1ea5..6d4bdae9 100644 --- a/ash/webui/diagnostics_ui/resources/connectivity_card.ts +++ b/ash/webui/diagnostics_ui/resources/connectivity_card.ts
@@ -11,6 +11,7 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './connectivity_card.html.js'; @@ -29,15 +30,15 @@ const ConnectivityCardElementBase = I18nMixin(PolymerElement); export class ConnectivityCardElement extends ConnectivityCardElementBase { - static get is() { + static get is(): string { return 'connectivity-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { testSuiteStatus: { type: Number, @@ -102,7 +103,7 @@ return routineSection; } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); this.getRoutineSectionElem_().stopTests();
diff --git a/ash/webui/diagnostics_ui/resources/cpu_card.ts b/ash/webui/diagnostics_ui/resources/cpu_card.ts index 2fbc810..64c051ef0 100644 --- a/ash/webui/diagnostics_ui/resources/cpu_card.ts +++ b/ash/webui/diagnostics_ui/resources/cpu_card.ts
@@ -14,6 +14,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './cpu_card.html.js'; @@ -30,26 +31,24 @@ const CpuCardElementBase = I18nMixin(PolymerElement); export class CpuCardElement extends CpuCardElementBase { - static get is() { + static get is(): string { return 'cpu-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { routines_: { type: Array, - value: () => { - return [ - RoutineType.kCpuStress, - RoutineType.kCpuCache, - RoutineType.kCpuFloatingPoint, - RoutineType.kCpuPrime, - ]; - }, + value: () => + [RoutineType.kCpuStress, + RoutineType.kCpuCache, + RoutineType.kCpuFloatingPoint, + RoutineType.kCpuPrime, + ], }, cpuUsage_: { @@ -89,7 +88,7 @@ this.fetchSystemInfo_(); } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); if (this.cpuUsageObserverReceiver_) {
diff --git a/ash/webui/diagnostics_ui/resources/data_point.ts b/ash/webui/diagnostics_ui/resources/data_point.ts index 6461218..0616cb7 100644 --- a/ash/webui/diagnostics_ui/resources/data_point.ts +++ b/ash/webui/diagnostics_ui/resources/data_point.ts
@@ -7,6 +7,7 @@ import './diagnostics_shared.css.js'; import './icons.html.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './data_point.html.js'; @@ -19,15 +20,15 @@ */ export class DataPointElement extends PolymerElement { - static get is() { + static get is(): string { return 'data-point'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { header: { type: String,
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.ts b/ash/webui/diagnostics_ui/resources/diagnostics_app.ts index 46df49e..022aee8 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.ts
@@ -19,6 +19,7 @@ import {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './diagnostics_app.html.js'; @@ -59,15 +60,15 @@ const DiagnosticsAppElementBase = I18nMixin(PolymerElement); export class DiagnosticsAppElement extends DiagnosticsAppElementBase { - static get is() { + static get is(): string { return 'diagnostics-app'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** * Used in navigation-view-panel to set show-banner when banner is @@ -130,7 +131,7 @@ * will contain message to display on message property of event found on * event found on path `e.detail.message`. */ - private showToastHandler = (e: ShowToastEvent) => { + private showToastHandler = (e: ShowToastEvent): void => { assert(e.detail.message); this.toastText_ = e.detail.message; this.$.toast.show(); @@ -203,14 +204,14 @@ this.$.navigationPanel.addSelectors(await this.getNavPages()); } - override connectedCallback() { + override connectedCallback(): void { super.connectedCallback(); this.createNavigationPanel(); window.addEventListener( 'show-toast', (e) => this.showToastHandler((e as ShowToastEvent))); } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); window.removeEventListener( 'show-toast', (e) => this.showToastHandler((e as ShowToastEvent)));
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts b/ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts index 4d2fb7d..678c4181 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts
@@ -70,7 +70,7 @@ return browserProxy || (browserProxy = new DiagnosticsBrowserProxyImpl()); } - static setInstance(obj: DiagnosticsBrowserProxyImpl) { + static setInstance(obj: DiagnosticsBrowserProxyImpl): void { browserProxy = obj; } }
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card.ts b/ash/webui/diagnostics_ui/resources/diagnostics_card.ts index c8d0d37b..d9b3cec 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card.ts
@@ -5,6 +5,7 @@ import './diagnostics_card_frame.js'; import './diagnostics_shared.css.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './diagnostics_card.html.js'; @@ -16,15 +17,15 @@ */ export class DiagnosticsCardElement extends PolymerElement { - static get is() { + static get is(): string { return 'diagnostics-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { hideDataPoints: { type: Boolean,
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.ts b/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.ts index 5baa66b..4bcda2e4 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.ts
@@ -15,11 +15,11 @@ */ class DiagnosticsCardFrameElement extends PolymerElement { - static get is() { + static get is(): string { return 'diagnostics-card-frame'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } }
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.ts b/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.ts index 957408f..497b2e05 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.ts
@@ -17,6 +17,7 @@ import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; import {CellularStateProperties, NetworkStateProperties, SecurityType as MojomSecurityType, WiFiStateProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {ConnectionStateType as MojomConnectionStateType, NetworkType as MojomNetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './diagnostics_network_icon.html.js'; @@ -215,15 +216,15 @@ const DiagnosticsNetworkIconBase = I18nMixin(PolymerElement); export class DiagnosticsNetworkIconElement extends DiagnosticsNetworkIconBase { - static get is() { + static get is(): string { return 'diagnostics-network-icon'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { network: { type: Object,
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.ts b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.ts index 3278478..9f8fd5f 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.ts
@@ -7,6 +7,7 @@ import './diagnostics_shared.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './diagnostics_sticky_banner.html.js'; @@ -21,15 +22,15 @@ } export class DiagnosticsStickyBannerElement extends PolymerElement { - static get is() { + static get is(): string { return 'diagnostics-sticky-banner'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { bannerMessage: { type: String, @@ -53,7 +54,7 @@ protected scrollingClass_: string; private scrollTimerId_: number; - override connectedCallback() { + override connectedCallback(): void { super.connectedCallback(); window.addEventListener( 'show-caution-banner', @@ -63,7 +64,7 @@ window.addEventListener('scroll', this.scrollClassHandler_); } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); window.removeEventListener( 'show-caution-banner', @@ -78,7 +79,7 @@ * section. Event will contain message to display on message property of * event found on path `event.detail.message`. */ - private showCautionBannerHandler_ = (e: ShowCautionBannerEvent) => { + private showCautionBannerHandler_ = (e: ShowCautionBannerEvent): void => { assert(e.detail.message); this.bannerMessage = e.detail.message; }; @@ -87,14 +88,14 @@ * Event callback for 'dismiss-caution-banner' which is triggered from * routine-section. */ - private dismissCautionBannerHandler_ = () => { + private dismissCautionBannerHandler_ = (): void => { this.bannerMessage = ''; }; /** * Event callback for 'scroll'. */ - private scrollClassHandler_ = () => { + private scrollClassHandler_ = (): void => { this.onScroll_(); };
diff --git a/ash/webui/diagnostics_ui/resources/drawing_provider.ts b/ash/webui/diagnostics_ui/resources/drawing_provider.ts index 79e4b2c..6372beb 100644 --- a/ash/webui/diagnostics_ui/resources/drawing_provider.ts +++ b/ash/webui/diagnostics_ui/resources/drawing_provider.ts
@@ -47,7 +47,7 @@ this.setup(); } - setup() { + setup(): void { assert(this.ctx); this.ctx.lineCap = LINE_CAP; this.ctx.lineWidth = LINE_WIDTH;
diff --git a/ash/webui/diagnostics_ui/resources/ethernet_info.ts b/ash/webui/diagnostics_ui/resources/ethernet_info.ts index e5add252..e4aec50 100644 --- a/ash/webui/diagnostics_ui/resources/ethernet_info.ts +++ b/ash/webui/diagnostics_ui/resources/ethernet_info.ts
@@ -6,6 +6,7 @@ import './diagnostics_shared.css.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './ethernet_info.html.js'; @@ -20,15 +21,15 @@ const EthernetInfoElementBase = I18nMixin(PolymerElement); export class EthernetInfoElement extends EthernetInfoElementBase { - static get is() { + static get is(): string { return 'ethernet-info'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { authentication_: { type: String, @@ -51,7 +52,7 @@ protected authentication_: string; protected ipAddress_: string; - protected computeAuthentication_() { + protected computeAuthentication_(): string { if (this.network?.typeProperties?.ethernet) { const authentication: AuthenticationType = this.network.typeProperties.ethernet.authentication;
diff --git a/ash/webui/diagnostics_ui/resources/input_card.ts b/ash/webui/diagnostics_ui/resources/input_card.ts index 09297f7..430430f 100644 --- a/ash/webui/diagnostics_ui/resources/input_card.ts +++ b/ash/webui/diagnostics_ui/resources/input_card.ts
@@ -12,6 +12,7 @@ import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './input_card.html.js'; @@ -43,15 +44,15 @@ const InputCardElementBase = I18nMixin(PolymerElement); export class InputCardElement extends InputCardElementBase { - static get is() { + static get is(): string { return 'input-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** * The type of input device to be displayed. Valid values are 'keyboard',
diff --git a/ash/webui/diagnostics_ui/resources/input_list.ts b/ash/webui/diagnostics_ui/resources/input_list.ts index 7c76a51..c7e49df 100644 --- a/ash/webui/diagnostics_ui/resources/input_list.ts +++ b/ash/webui/diagnostics_ui/resources/input_list.ts
@@ -10,6 +10,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {DiagnosticsBrowserProxy, DiagnosticsBrowserProxyImpl} from './diagnostics_browser_proxy.js'; @@ -35,15 +36,15 @@ } export class InputListElement extends InputListElementBase { - static get is() { + static get is(): string { return 'input-list'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { keyboards_: { type: Array, @@ -124,7 +125,7 @@ this.observeTabletMode(); } - override connectedCallback() { + override connectedCallback(): void { super.connectedCallback(); const keyboardTester = this.shadowRoot!.querySelector('keyboard-tester'); assert(keyboardTester); @@ -215,7 +216,7 @@ */ private removeDeviceById_( - path: 'keyboards_'|'touchpads_'|'touchscreens_', id: number) { + path: 'keyboards_'|'touchpads_'|'touchscreens_', id: number): void { const index = this.get(path).findIndex( (device: KeyboardInfo|TouchDeviceInfo) => device.id === id); if (index !== -1) {
diff --git a/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.ts b/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.ts index 25c6f86..a33fd28 100644 --- a/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.ts +++ b/ash/webui/diagnostics_ui/resources/ip_config_info_drawer.ts
@@ -8,6 +8,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {DiagnosticsBrowserProxyImpl} from './diagnostics_browser_proxy.js'; @@ -24,15 +25,15 @@ const IpConfigInfoDrawerElementBase = I18nMixin(PolymerElement); export class IpConfigInfoDrawerElement extends IpConfigInfoDrawerElementBase { - static get is() { + static get is(): string { return 'ip-config-info-drawer'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { expanded_: { type: Boolean, @@ -74,7 +75,7 @@ private browserProxy_: DiagnosticsBrowserProxyImpl = DiagnosticsBrowserProxyImpl.getInstance(); - static get observers() { + static get observers(): string[] { return ['getNameServersHeader_(network.ipConfig.nameServers)']; }
diff --git a/ash/webui/diagnostics_ui/resources/keyboard_tester.ts b/ash/webui/diagnostics_ui/resources/keyboard_tester.ts index df8aab5..c59ed30a 100644 --- a/ash/webui/diagnostics_ui/resources/keyboard_tester.ts +++ b/ash/webui/diagnostics_ui/resources/keyboard_tester.ts
@@ -17,6 +17,7 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {InputDataProviderInterface, KeyboardInfo, KeyboardObserverReceiver, KeyEvent, KeyEventType, MechanicalLayout, NumberPadPresence, PhysicalLayout, TopRightKey, TopRowKey} from './input_data_provider.mojom-webui.js'; @@ -124,15 +125,15 @@ const KeyboardTesterElementBase = I18nMixin(PolymerElement); export class KeyboardTesterElement extends KeyboardTesterElementBase { - static get is() { + static get is(): string { return 'keyboard-tester'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** * The keyboard being tested, or null if none is being tested at the @@ -205,7 +206,7 @@ getInputDataProvider(); private eventTracker: EventTracker = new EventTracker(); - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); this.eventTracker.removeAll(); } @@ -214,7 +215,7 @@ * Event callback for 'announce-text' which is triggered from keyboard-key. * Event will contain text to announce to screen readers. */ - private announceTextHandler = (e: AnnounceTextEvent) => { + private announceTextHandler = (e: AnnounceTextEvent): void => { assert(e.detail.text); e.stopPropagation(); getInstance(this.$.dialog.getNative()).announce(e.detail.text);
diff --git a/ash/webui/diagnostics_ui/resources/memory_card.ts b/ash/webui/diagnostics_ui/resources/memory_card.ts index e89460f..9f2f759 100644 --- a/ash/webui/diagnostics_ui/resources/memory_card.ts +++ b/ash/webui/diagnostics_ui/resources/memory_card.ts
@@ -14,6 +14,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {convertKibToGibDecimalString, convertKibToMib} from './diagnostics_utils.js'; @@ -31,15 +32,15 @@ const MemoryCardElementBase = I18nMixin(PolymerElement); export class MemoryCardElement extends MemoryCardElementBase { - static get is() { + static get is(): string { return 'memory-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { routines_: { type: Array, @@ -75,7 +76,7 @@ this.observeMemoryUsage_(); } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); if (this.memoryUsageObserverReceiver_) { this.memoryUsageObserverReceiver_.$.close();
diff --git a/ash/webui/diagnostics_ui/resources/network_card.ts b/ash/webui/diagnostics_ui/resources/network_card.ts index f5c010c..cce80572 100644 --- a/ash/webui/diagnostics_ui/resources/network_card.ts +++ b/ash/webui/diagnostics_ui/resources/network_card.ts
@@ -10,6 +10,7 @@ import './network_troubleshooting.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {TroubleshootingInfo} from './diagnostics_types.js'; @@ -39,15 +40,15 @@ const NetworkCardElementBase = I18nMixin(PolymerElement); export class NetworkCardElement extends NetworkCardElementBase { - static get is() { + static get is(): string { return 'network-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { guid: { type: String, @@ -130,11 +131,11 @@ private networkStateObserverReceiver_: NetworkStateObserverReceiver|null = null; - static get observers() { + static get observers(): string[] { return ['observeNetwork_(guid)']; } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); this.resetTimer_();
diff --git a/ash/webui/diagnostics_ui/resources/network_info.ts b/ash/webui/diagnostics_ui/resources/network_info.ts index c09ca25..f15b438 100644 --- a/ash/webui/diagnostics_ui/resources/network_info.ts +++ b/ash/webui/diagnostics_ui/resources/network_info.ts
@@ -7,6 +7,7 @@ import './ethernet_info.js'; import './wifi_info.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {Network, NetworkType} from './network_health_provider.mojom-webui.js'; @@ -19,15 +20,15 @@ */ export class NetworkInfoElement extends PolymerElement { - static get is() { + static get is(): string { return 'network-info'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** @type {!Network} */ network: {
diff --git a/ash/webui/diagnostics_ui/resources/network_list.ts b/ash/webui/diagnostics_ui/resources/network_list.ts index ef01dfc..bb55f940 100644 --- a/ash/webui/diagnostics_ui/resources/network_list.ts +++ b/ash/webui/diagnostics_ui/resources/network_list.ts
@@ -10,6 +10,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {ConnectivityCardElement} from './connectivity_card.js'; @@ -35,15 +36,15 @@ const NetworkListElementBase = I18nMixin(PolymerElement); export class NetworkListElement extends NetworkListElementBase { - static get is() { + static get is(): string { return 'network-list'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { testSuiteStatus: { type: Number, @@ -90,7 +91,7 @@ this.observeNetworkList_(); } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); if (this.networkListObserverReceiver_) {
diff --git a/ash/webui/diagnostics_ui/resources/network_troubleshooting.ts b/ash/webui/diagnostics_ui/resources/network_troubleshooting.ts index 279d71b..f8f95d35 100644 --- a/ash/webui/diagnostics_ui/resources/network_troubleshooting.ts +++ b/ash/webui/diagnostics_ui/resources/network_troubleshooting.ts
@@ -6,6 +6,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {TroubleshootingInfo} from './diagnostics_types.js'; @@ -15,15 +16,15 @@ export class NetworkTroubleshootingElement extends NetworkTroubleshootingElementBase { - static get is() { + static get is(): string { return 'network-troubleshooting'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { isLoggedIn_: { type: Boolean,
diff --git a/ash/webui/diagnostics_ui/resources/overview_card.ts b/ash/webui/diagnostics_ui/resources/overview_card.ts index d54aae6..500e410 100644 --- a/ash/webui/diagnostics_ui/resources/overview_card.ts +++ b/ash/webui/diagnostics_ui/resources/overview_card.ts
@@ -5,6 +5,7 @@ import './diagnostics_shared.css.js'; import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getSystemDataProvider} from './mojo_interface_provider.js'; @@ -18,15 +19,15 @@ */ export class OverviewCardElement extends PolymerElement { - static get is() { + static get is(): string { return 'overview-card'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { systemInfo_: { type: Object,
diff --git a/ash/webui/diagnostics_ui/resources/percent_bar_chart.ts b/ash/webui/diagnostics_ui/resources/percent_bar_chart.ts index 1e2b9d4..139d741 100644 --- a/ash/webui/diagnostics_ui/resources/percent_bar_chart.ts +++ b/ash/webui/diagnostics_ui/resources/percent_bar_chart.ts
@@ -8,6 +8,7 @@ import './diagnostics_shared.css.js'; import './strings.m.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './percent_bar_chart.html.js'; @@ -19,15 +20,15 @@ */ export class PercentBarChartElement extends PolymerElement { - static get is() { + static get is(): string { return 'percent-bar-chart'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { header: { type: String,
diff --git a/ash/webui/diagnostics_ui/resources/routine_result_entry.ts b/ash/webui/diagnostics_ui/resources/routine_result_entry.ts index 9ef2b8d..909b045b 100644 --- a/ash/webui/diagnostics_ui/resources/routine_result_entry.ts +++ b/ash/webui/diagnostics_ui/resources/routine_result_entry.ts
@@ -9,6 +9,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getRoutineFailureMessage} from './diagnostics_utils.js'; @@ -92,15 +93,15 @@ */ export class RoutineResultEntryElement extends PolymerElement { - static get is() { + static get is(): string { return 'routine-result-entry'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** * Added to support testing of announce behavior. @@ -157,11 +158,11 @@ private routineType_: string; - static get observers() { + static get observers(): string[] { return ['entryStatusChanged_(item.*)']; } - override connectedCallback() { + override connectedCallback(): void { super.connectedCallback(); IronA11yAnnouncer.requestAvailability();
diff --git a/ash/webui/diagnostics_ui/resources/routine_result_list.ts b/ash/webui/diagnostics_ui/resources/routine_result_list.ts index a4a1145..9a22d343 100644 --- a/ash/webui/diagnostics_ui/resources/routine_result_list.ts +++ b/ash/webui/diagnostics_ui/resources/routine_result_list.ts
@@ -7,6 +7,7 @@ import './routine_result_entry.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {RoutineGroup} from './routine_group.js'; @@ -29,15 +30,15 @@ */ export class RoutineResultListElement extends PolymerElement { - static get is() { + static get is(): string { return 'routine-result-list'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { results_: { type: Array,
diff --git a/ash/webui/diagnostics_ui/resources/routine_section.ts b/ash/webui/diagnostics_ui/resources/routine_section.ts index 0462d66..91923fa 100644 --- a/ash/webui/diagnostics_ui/resources/routine_section.ts +++ b/ash/webui/diagnostics_ui/resources/routine_section.ts
@@ -17,6 +17,7 @@ import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; import {IronCollapseElement} from 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getSystemRoutineController} from './mojo_interface_provider.js'; @@ -46,15 +47,15 @@ const RoutineSectionElementBase = I18nMixin(PolymerElement); export class RoutineSectionElement extends RoutineSectionElementBase { - static get is() { + static get is(): string { return 'routine-section'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** * Added to support testing of announce behavior. @@ -226,7 +227,7 @@ private systemRoutineController_: SystemRoutineControllerInterface|null = null; - static get observers() { + static get observers(): string[] { return [ 'routineStatusChanged_(executionStatus_, currentTestName_,' + 'additionalMessage)', @@ -235,7 +236,7 @@ ]; } - override connectedCallback() { + override connectedCallback(): void { super.connectedCallback(); IronA11yAnnouncer.requestAvailability(); @@ -602,7 +603,7 @@ return !this.isLoggedIn_ || this.hideRoutineStatus; } - override disconnectedCallback() { + override disconnectedCallback(): void { super.disconnectedCallback(); this.cleanUp_();
diff --git a/ash/webui/diagnostics_ui/resources/system_page.ts b/ash/webui/diagnostics_ui/resources/system_page.ts index 12f68e1..1c177363 100644 --- a/ash/webui/diagnostics_ui/resources/system_page.ts +++ b/ash/webui/diagnostics_ui/resources/system_page.ts
@@ -17,6 +17,7 @@ import {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {DiagnosticsBrowserProxyImpl} from './diagnostics_browser_proxy.js'; @@ -41,15 +42,15 @@ const SystemPageElementBase = I18nMixin(PolymerElement); export class SystemPageElement extends SystemPageElementBase { - static get is() { + static get is(): string { return 'system-page'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { saveSessionLogEnabled_: { type: Boolean,
diff --git a/ash/webui/diagnostics_ui/resources/text_badge.ts b/ash/webui/diagnostics_ui/resources/text_badge.ts index c9b29aad..11ff88a 100644 --- a/ash/webui/diagnostics_ui/resources/text_badge.ts +++ b/ash/webui/diagnostics_ui/resources/text_badge.ts
@@ -4,6 +4,7 @@ import './diagnostics_shared.css.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './text_badge.html.js'; @@ -28,15 +29,15 @@ */ export class TextBadgeElement extends PolymerElement { - static get is() { + static get is(): string { return 'text-badge'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { badgeType: { type: String,
diff --git a/ash/webui/diagnostics_ui/resources/touchpad_tester.ts b/ash/webui/diagnostics_ui/resources/touchpad_tester.ts index 1166b88..8804a6eed 100644 --- a/ash/webui/diagnostics_ui/resources/touchpad_tester.ts +++ b/ash/webui/diagnostics_ui/resources/touchpad_tester.ts
@@ -42,7 +42,7 @@ export class TouchpadTesterElement extends TouchpadTesterElementBase implements TouchEventObserver { - static get is() { + static get is(): string { return 'touchpad-tester'; } @@ -58,7 +58,7 @@ // Touchpad device being tested. touchpad: TouchDeviceInfo|null = null; - override connectedCallback() { + override connectedCallback(): void { super.connectedCallback(); const ctx = this.$.testerCanvas.getContext('2d'); assert(!!ctx);
diff --git a/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts b/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts index 1d6f3fe..cd4430e 100644 --- a/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts +++ b/ash/webui/diagnostics_ui/resources/touchscreen_tester.ts
@@ -8,6 +8,7 @@ import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {CanvasDrawingProvider} from './drawing_provider.js'; @@ -44,15 +45,15 @@ const TouchscreenTesterElementBase = I18nMixin(PolymerElement); export class TouchscreenTesterElement extends TouchscreenTesterElementBase { - static get is() { + static get is(): string { return 'touchscreen-tester'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { touchscreenIdUnderTesting: { type: Number, @@ -299,7 +300,7 @@ * Implements TabletModeObserver.OnTabletModeChanged. * @param isTabletMode Is current display on tablet mode. */ - onTabletModeChanged(isTabletMode: boolean) { + onTabletModeChanged(isTabletMode: boolean): void { this.isTabletMode = isTabletMode; // TODO(wenyu): Show exit instruction toaster. }
diff --git a/ash/webui/diagnostics_ui/resources/wifi_info.ts b/ash/webui/diagnostics_ui/resources/wifi_info.ts index b42cd1d7..20880ff 100644 --- a/ash/webui/diagnostics_ui/resources/wifi_info.ts +++ b/ash/webui/diagnostics_ui/resources/wifi_info.ts
@@ -8,6 +8,7 @@ import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assertNotReached} from 'chrome://resources/js/assert_ts.js'; +import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getSignalStrength} from './diagnostics_utils.js'; @@ -26,15 +27,15 @@ export class WifiInfoElement extends WifiInfoElementBase { - static get is() { + static get is(): string { return 'wifi-info'; } - static get template() { + static get template(): HTMLTemplateElement { return getTemplate(); } - static get properties() { + static get properties(): PolymerElementProperties { return { /** @type {!Network} */ network: {
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_observer.ts b/ash/webui/personalization_app/resources/js/ambient/ambient_observer.ts index 55f2b28..18ffa8e3 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_observer.ts +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_observer.ts
@@ -5,7 +5,10 @@ import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {AmbientModeAlbum, AmbientObserverInterface, AmbientObserverReceiver, AmbientProviderInterface, AmbientUiVisibility, AnimationTheme, TemperatureUnit, TopicSource} from '../personalization_app.mojom-webui.js'; +import {logGooglePhotosPreviewsLoadTime} from '../personalization_metrics_logger.js'; +import {Paths} from '../personalization_router_element.js'; import {PersonalizationStore} from '../personalization_store.js'; +import {isNonEmptyArray} from '../utils.js'; import {setAlbumsAction, setAmbientModeEnabledAction, setAmbientUiVisibilityAction, setAnimationThemeAction, setGooglePhotosAlbumsPreviewsAction, setTemperatureUnitAction, setTopicSourceAction} from './ambient_actions.js'; import {getAmbientProvider} from './ambient_interface_provider.js'; @@ -19,6 +22,12 @@ * Observes ambient mode changes and saves updates to PersonalizationStore. */ export class AmbientObserver implements AmbientObserverInterface { + // Allow logging first load performance if the user began on a page where + // google photos preview images are loaded immediately. + static shouldLogGooglePhotosPreviewsLoadPerformance: boolean = + window.location.pathname === Paths.ROOT || + window.location.pathname === Paths.AMBIENT; + static initAmbientObserverIfNeeded(): void { if (!instance) { instance = new AmbientObserver(); @@ -48,6 +57,11 @@ } onAmbientModeEnabledChanged(ambientModeEnabled: boolean) { + // Only record google photos previews load performance if ambient mode + // starts enabled. + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance = + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance && + ambientModeEnabled; const store = PersonalizationStore.getInstance(); store.dispatch(setAmbientModeEnabledAction(ambientModeEnabled)); } @@ -59,6 +73,12 @@ onTopicSourceChanged(topicSource: TopicSource) { const store = PersonalizationStore.getInstance(); + // If the first time receiving `topicSource` and it is already set to + // `kGooglePhotos`, allow logging google photos load performance. + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance = + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance && + store.data.ambient.topicSource === null && + topicSource === TopicSource.kGooglePhotos; store.dispatch(setTopicSourceAction(topicSource)); } @@ -89,7 +109,21 @@ onGooglePhotosAlbumsPreviewsFetched(previews: Url[]) { const store = PersonalizationStore.getInstance(); + + // Only log performance metrics if this is the first time receiving google + // photos previews. + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance = + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance && + (!store.data.ambient.googlePhotosAlbumsPreviews || + store.data.ambient.googlePhotosAlbumsPreviews.length === 0); + store.dispatch(setGooglePhotosAlbumsPreviewsAction(previews)); + + if (AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance && + isNonEmptyArray(previews)) { + logGooglePhotosPreviewsLoadTime(); + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance = false; + } } onAmbientUiVisibilityChanged(ambientUiVisibility: AmbientUiVisibility) {
diff --git a/ash/webui/personalization_app/resources/js/personalization_metrics_logger.ts b/ash/webui/personalization_app/resources/js/personalization_metrics_logger.ts index 049d4a2..f1d8993 100644 --- a/ash/webui/personalization_app/resources/js/personalization_metrics_logger.ts +++ b/ash/webui/personalization_app/resources/js/personalization_metrics_logger.ts
@@ -22,9 +22,12 @@ MAX_VALUE = USER, } -const PersonalizationPathHistogramName: string = 'Ash.Personalization.Path'; -const PersonalizationAmbientModeOptInHistogramName: string = - 'Ash.Personalization.AmbientMode.OptIn'; +const enum HistogramName { + PATH = 'Ash.Personalization.Path', + AMBIENT_OPTIN = 'Ash.Personalization.AmbientMode.OptIn', + AMBIENT_PERFORMANCE_GOOGLE_PHOTOS_PREVIEWS = + 'Ash.Personalization.Ambient.GooglePhotosPreviewsLoadTime', +} function toMetricsEnum(path: Paths) { switch (path) { @@ -51,10 +54,18 @@ const metricsPath = toMetricsEnum(path); assert(metricsPath <= MetricsPath.MAX_VALUE); chrome.metricsPrivate.recordEnumerationValue( - PersonalizationPathHistogramName, metricsPath, MetricsPath.MAX_VALUE + 1); + HistogramName.PATH, metricsPath, MetricsPath.MAX_VALUE + 1); } export function logAmbientModeOptInUMA() { - chrome.metricsPrivate.recordBoolean( - PersonalizationAmbientModeOptInHistogramName, true); + chrome.metricsPrivate.recordBoolean(HistogramName.AMBIENT_OPTIN, true); +} + +export function logGooglePhotosPreviewsLoadTime() { + // Get elapsed time in ms since the page initialized. + const timeMs = Math.round(performance.now()); + console.debug( + HistogramName.AMBIENT_PERFORMANCE_GOOGLE_PHOTOS_PREVIEWS, timeMs); + chrome.metricsPrivate.recordTime( + HistogramName.AMBIENT_PERFORMANCE_GOOGLE_PHOTOS_PREVIEWS, timeMs); }
diff --git a/ash/webui/personalization_app/resources/tsconfig_base.json b/ash/webui/personalization_app/resources/tsconfig_base.json index 3e71f763..a4137c0 100644 --- a/ash/webui/personalization_app/resources/tsconfig_base.json +++ b/ash/webui/personalization_app/resources/tsconfig_base.json
@@ -1,6 +1,7 @@ { "extends": "../../../../tools/typescript/tsconfig_base.json", "compilerOptions": { + "target": "es2021", "allowJs": true, "noUncheckedIndexedAccess": false, "noUnusedLocals": false,
diff --git a/ash/webui/shimless_rma/resources/calibration_component_chip.js b/ash/webui/shimless_rma/resources/calibration_component_chip.js index 363b44c6b..4f3b1ce 100644 --- a/ash/webui/shimless_rma/resources/calibration_component_chip.js +++ b/ash/webui/shimless_rma/resources/calibration_component_chip.js
@@ -56,7 +56,8 @@ isFirstClickableComponent: { type: Boolean, value: false, - observer: 'onIsFirstClickableComponentChanged_', + observer: CalibrationComponentChipElement.prototype + .onIsFirstClickableComponentChanged_, }, /** @type {number} */
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js index a6b2c5d..5d15113 100644 --- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js
@@ -57,7 +57,8 @@ */ errorCode: { type: Object, - observer: 'onErrorCodeChanged_', + observer: + OnboardingEnterRsuWpDisableCodePage.prototype.onErrorCodeChanged_, }, /** @protected */ @@ -82,7 +83,8 @@ rsuCode_: { type: String, value: '', - observer: 'onRsuCodeChanged_', + observer: + OnboardingEnterRsuWpDisableCodePage.prototype.onRsuCodeChanged_, }, /** @protected */
diff --git a/ash/webui/shimless_rma/resources/onboarding_network_page.js b/ash/webui/shimless_rma/resources/onboarding_network_page.js index 57c0711f..c94e0c0 100644 --- a/ash/webui/shimless_rma/resources/onboarding_network_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_network_page.js
@@ -132,7 +132,7 @@ isOnline_: { type: Boolean, value: false, - observer: 'onIsOnlineChange_', + observer: OnboardingNetworkPage.prototype.onIsOnlineChange_, }, }; }
diff --git a/ash/webui/shimless_rma/resources/onboarding_update_page.js b/ash/webui/shimless_rma/resources/onboarding_update_page.js index 28f845e..740fb97 100644 --- a/ash/webui/shimless_rma/resources/onboarding_update_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_update_page.js
@@ -82,7 +82,8 @@ updateInProgress_: { type: Boolean, value: false, - observer: 'onUpdateInProgressChange_', + observer: + OnboardingUpdatePageElement.prototype.onUpdateInProgressChange_, }, /** @protected */
diff --git a/ash/webui/shimless_rma/resources/repair_component_chip.js b/ash/webui/shimless_rma/resources/repair_component_chip.js index 7894cf7..3b900da 100644 --- a/ash/webui/shimless_rma/resources/repair_component_chip.js +++ b/ash/webui/shimless_rma/resources/repair_component_chip.js
@@ -71,7 +71,8 @@ isFirstClickableComponent: { type: Boolean, value: false, - observer: 'onIsFirstClickableComponentChanged_', + observer: + RepairComponentChip.prototype.onIsFirstClickableComponentChanged_, }, };
diff --git a/ash/wm/ash_focus_rules.cc b/ash/wm/ash_focus_rules.cc index 6f09f03d..2b72c28ca 100644 --- a/ash/wm/ash_focus_rules.cc +++ b/ash/wm/ash_focus_rules.cc
@@ -95,12 +95,19 @@ if (window_state->IsMinimized()) return true; - // Floated windows are hidden if they belong to inactive desks, but they can - // always be activated. - if (window_state->IsFloated() && - shell->float_controller()->FindDeskOfFloatedWindow(window) != - DesksController::Get()->active_desk()) { - return true; + if (window_state->IsFloated()) { + auto* float_controller = shell->float_controller(); + // Floated windows are hidden if they belong to inactive desks, but they can + // always be activated. + if (float_controller->FindDeskOfFloatedWindow(window) != + DesksController::Get()->active_desk()) { + return true; + } + + // Tucked windows are hidden offscreen, but they can be activated. + if (float_controller->IsFloatedWindowTuckedForTablet(window)) { + return true; + } } if (!window->TargetVisibility())
diff --git a/ash/wm/desks/cros_next_desk_button.cc b/ash/wm/desks/cros_next_desk_button.cc new file mode 100644 index 0000000..0adc51d --- /dev/null +++ b/ash/wm/desks/cros_next_desk_button.cc
@@ -0,0 +1,181 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/desks/cros_next_desk_button.h" + +#include "ash/strings/grit/ash_strings.h" +#include "ash/style/ash_color_id.h" +#include "ash/wm/desks/desk.h" +#include "ash/wm/desks/desk_mini_view.h" +#include "ash/wm/desks/desk_preview_view.h" +#include "ash/wm/desks/desks_bar_view.h" +#include "ash/wm/desks/desks_controller.h" +#include "ash/wm/overview/overview_constants.h" +#include "base/check_op.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/geometry/rounded_corners_f.h" +#include "ui/gfx/text_elider.h" +#include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/background.h" +#include "ui/views/controls/highlight_path_generator.h" + +namespace ash { + +namespace { + +constexpr int kIconButtonCornerRadius = 18; + +constexpr int kDefaultButtonCornerRadius = 14; + +constexpr int kZeroStateButtonHeight = 28; + +constexpr int kZeroStateButtonWidth = 28; + +constexpr int kExpandedStateButtonWidth = 44; + +constexpr int kDefaultButtonHorizontalPadding = 16; + +constexpr int kDefaultDeskButtonMinWidth = 56; + +} // namespace + +// ----------------------------------------------------------------------------- +// CrOSNextDefaultDeskButton: + +CrOSNextDefaultDeskButton::CrOSNextDefaultDeskButton(DesksBarView* bar_view) + : CrOSNextDeskButtonBase( + DesksController::Get()->desks()[0]->name(), + /*set_text=*/true, + base::BindRepeating(&CrOSNextDefaultDeskButton::OnButtonPressed, + base::Unretained(this))), + bar_view_(bar_view) { + layer()->SetRoundedCornerRadius( + gfx::RoundedCornersF(kDefaultButtonCornerRadius)); + GetViewAccessibility().OverrideName( + l10n_util::GetStringFUTF16(IDS_ASH_DESKS_DESK_ACCESSIBLE_NAME, + DesksController::Get()->desks()[0]->name())); + + SetBackground( + views::CreateThemedSolidBackground(cros_tokens::kCrosSysSystemOnBase)); +} + +gfx::Size CrOSNextDefaultDeskButton::CalculatePreferredSize() const { + auto* root_window = + bar_view_->GetWidget()->GetNativeWindow()->GetRootWindow(); + const int preview_width = DeskMiniView::GetPreviewWidth( + root_window->bounds().size(), DeskPreviewView::GetHeight(root_window)); + int label_width = 0, label_height = 0; + gfx::Canvas::SizeStringInt(DesksController::Get()->desks()[0]->name(), + gfx::FontList(), &label_width, &label_height, 0, + gfx::Canvas::NO_ELLIPSIS); + + // `preview_width` is supposed to be larger than + // `kZeroStateDefaultDeskButtonMinWidth`, but it might be not the truth for + // tests with extreme abnormal size of display. + const int min_width = std::min(preview_width, kDefaultDeskButtonMinWidth); + const int max_width = std::max(preview_width, kDefaultDeskButtonMinWidth); + const int width = base::clamp( + label_width + 2 * kDefaultButtonHorizontalPadding, min_width, max_width); + return gfx::Size(width, kZeroStateButtonHeight); +} + +void CrOSNextDefaultDeskButton::UpdateLabelText() { + SetText(gfx::ElideText( + DesksController::Get()->desks()[0]->name(), gfx::FontList(), + bounds().width() - 2 * kDefaultButtonHorizontalPadding, gfx::ELIDE_TAIL)); +} + +void CrOSNextDefaultDeskButton::OnButtonPressed() { + bar_view_->UpdateNewMiniViews(/*initializing_bar_view=*/false, + /*expanding_bar_view=*/true); + bar_view_->NudgeDeskName(/*desk_index=*/0); +} + +BEGIN_METADATA(CrOSNextDefaultDeskButton, CrOSNextDeskButtonBase) +END_METADATA + +// ----------------------------------------------------------------------------- +// CrOSNextDeskIconButton: + +CrOSNextDeskIconButton::CrOSNextDeskIconButton( + DesksBarView* bar_view, + const gfx::VectorIcon* button_icon, + const std::u16string& text, + ui::ColorId icon_color_id, + ui::ColorId background_color_id, + base::RepeatingClosure callback) + : CrOSNextDeskButtonBase(text, /*set_text=*/false, callback), + bar_view_(bar_view), + state_(bar_view_->IsZeroState() ? State::kZero : State::kExpanded) { + layer()->SetRoundedCornerRadius( + gfx::RoundedCornersF(kIconButtonCornerRadius)); + SetImageModel(views::Button::STATE_NORMAL, + ui::ImageModel::FromVectorIcon(*button_icon, icon_color_id)); + SetBackground(views::CreateThemedSolidBackground(background_color_id)); + + views::InstallRoundRectHighlightPathGenerator( + this, gfx::Insets(kFocusRingHaloInset), kIconButtonCornerRadius); + views::FocusRing::Get(this)->SetHasFocusPredicate([&](views::View* view) { + return IsViewHighlighted() || + ((bar_view_->dragged_item_over_bar() && + IsPointOnButton(bar_view_->last_dragged_item_screen_location())) || + paint_as_active_); + }); +} + +CrOSNextDeskIconButton::~CrOSNextDeskIconButton() = default; + +bool CrOSNextDeskIconButton::IsPointOnButton( + const gfx::Point& screen_location) const { + gfx::Point point_in_view = screen_location; + ConvertPointFromScreen(this, &point_in_view); + return HitTestPoint(point_in_view); +} + +gfx::Size CrOSNextDeskIconButton::CalculatePreferredSize() const { + if (state_ == State::kZero) { + return gfx::Size(kZeroStateButtonWidth, kZeroStateButtonHeight); + } + + gfx::Rect desk_preview_bounds = DeskMiniView::GetDeskPreviewBounds( + GetWidget()->GetNativeWindow()->GetRootWindow()); + if (state_ == State::kExpanded) { + return gfx::Size(kExpandedStateButtonWidth, desk_preview_bounds.height()); + } + + DCHECK_EQ(state_, State::kDragAndDrop); + return gfx::Size(desk_preview_bounds.width(), desk_preview_bounds.height()); +} + +void CrOSNextDeskIconButton::UpdateFocusState() { + absl::optional<ui::ColorId> new_focus_color_id; + + if (IsViewHighlighted() || + (bar_view_->dragged_item_over_bar() && + IsPointOnButton(bar_view_->last_dragged_item_screen_location()))) { + new_focus_color_id = ui::kColorAshFocusRing; + } else if (paint_as_active_) { + new_focus_color_id = kColorAshCurrentDeskColor; + } else { + new_focus_color_id = absl::nullopt; + } + + if (focus_color_id_ == new_focus_color_id) { + return; + } + + focus_color_id_ = new_focus_color_id; + + // Only repaint the focus ring if the color gets updated. + auto* focus_ring = views::FocusRing::Get(this); + focus_ring->SetColorId(new_focus_color_id); + focus_ring->SchedulePaint(); +} + +BEGIN_METADATA(CrOSNextDeskIconButton, CrOSNextDeskButtonBase) +END_METADATA + +} // namespace ash
diff --git a/ash/wm/desks/cros_next_desk_button.h b/ash/wm/desks/cros_next_desk_button.h new file mode 100644 index 0000000..1cb75d6 --- /dev/null +++ b/ash/wm/desks/cros_next_desk_button.h
@@ -0,0 +1,100 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_DESKS_CROS_NEXT_DESK_BUTTON_H_ +#define ASH_WM_DESKS_CROS_NEXT_DESK_BUTTON_H_ + +#include "ash/wm/desks/cros_next_desk_button_base.h" +#include "ui/base/metadata/metadata_impl_macros.h" + +namespace gfx { +struct VectorIcon; +} + +namespace ash { + +class DesksBarView; + +// A button in zero state bar showing the name of the desk. Zero state is the +// state of the desks bar when there's only a single desk available, in which +// case the bar is shown in a minimized state. Clicking the button will switch +// to the expanded desks bar and focus on the single desk's name view. +// TODO(conniekxu): Remove `ZeroStateDefaultDeskButton`, replace it with this +// class, and rename this class by removing the prefix CrOSNext. +class CrOSNextDefaultDeskButton : public CrOSNextDeskButtonBase { + public: + METADATA_HEADER(CrOSNextDefaultDeskButton); + + explicit CrOSNextDefaultDeskButton(DesksBarView* bar_view); + CrOSNextDefaultDeskButton(const CrOSNextDefaultDeskButton&) = delete; + CrOSNextDefaultDeskButton& operator=(const CrOSNextDefaultDeskButton&) = + delete; + ~CrOSNextDefaultDeskButton() override = default; + + void UpdateLabelText(); + + // CrOSNextDeskButtonBase: + gfx::Size CalculatePreferredSize() const override; + + private: + void OnButtonPressed(); + + DesksBarView* const bar_view_; +}; + +// A button view in the desks bar with an icon. The button have three different +// states, and the three states are interchangeable. +// TODO(conniekxu): Remove `ZeroStateIconButton` and `ExpandedDesksBarButton`, +// replace them with this class, and rename this class by removing the prefix +// CrOSNext. +class CrOSNextDeskIconButton : public CrOSNextDeskButtonBase { + public: + METADATA_HEADER(CrOSNextDeskIconButton); + + // The enum class defines three states for the button. The button at different + // states has different sizes. Any state could be transformed into another + // state under certain conditions. + enum class State { + // The state of the button when the DesksBarView is in zero state. + kZero, + // The state of the button when the DesksBarView is in expanded state. + kExpanded, + // The state of when a window is dragged over the new desk button and held + // for 500 milliseconds, we can create a new desk. The new desk button state + // will change to reflect that. + kDragAndDrop, + }; + + CrOSNextDeskIconButton(DesksBarView* bar_view, + const gfx::VectorIcon* button_icon, + const std::u16string& text, + ui::ColorId icon_color_id, + ui::ColorId background_color_id, + base::RepeatingClosure callback); + CrOSNextDeskIconButton(const CrOSNextDeskIconButton&) = delete; + CrOSNextDeskIconButton& operator=(const CrOSNextDeskIconButton&) = delete; + ~CrOSNextDeskIconButton() override; + + bool IsPointOnButton(const gfx::Point& screen_location) const; + + // CrOSNextDeskButtonBase: + gfx::Size CalculatePreferredSize() const override; + // Updates the focus ring based on the dragged item's position and `active_`. + void UpdateFocusState() override; + + private: + DesksBarView* const bar_view_; + + State state_; + + // If `active_` is true, then focus ring will be painted with color id + // `kColorAshCurrentDeskColor` even if it's not already focused. + bool paint_as_active_ = false; + + absl::optional<ui::ColorId> focus_color_id_; +}; + +} // namespace ash + +#endif // ASH_WM_DESKS_CROS_NEXT_DESK_BUTTON_H_
diff --git a/ash/wm/desks/cros_next_desk_button_base.cc b/ash/wm/desks/cros_next_desk_button_base.cc new file mode 100644 index 0000000..e372d352 --- /dev/null +++ b/ash/wm/desks/cros_next_desk_button_base.cc
@@ -0,0 +1,92 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wm/desks/cros_next_desk_button_base.h" + +#include "ash/wm/overview/overview_utils.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/compositor/layer.h" +#include "ui/views/border.h" +#include "ui/views/controls/focus_ring.h" +#include "ui/views/controls/highlight_path_generator.h" + +namespace ash { + +namespace { + +constexpr int kFocusRingRadius = 8; + +} // namespace + +CrOSNextDeskButtonBase::CrOSNextDeskButtonBase( + const std::u16string& text, + bool set_text, + base::RepeatingClosure pressed_callback) + : LabelButton(pressed_callback), pressed_callback_(pressed_callback) { + DCHECK(!text.empty()); + if (set_text) { + SetText(text); + } + + // Call `SetPaintToLayer` explicitly here since we need to do the layer + // animations on `this`. + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + + SetAccessibleName(text); + SetTooltipText(text); + + // Create an empty border, otherwise in `LabelButton` a default border with + // non-empty insets will be created. + SetBorder(views::CreateEmptyBorder(gfx::Insets())); + + views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(), + kFocusRingRadius); + views::FocusRing* focus_ring = views::FocusRing::Get(this); + focus_ring->SetColorId(ui::kColorAshFocusRing); + focus_ring->SetHasFocusPredicate( + [&](views::View* view) { return IsViewHighlighted(); }); +} + +CrOSNextDeskButtonBase::~CrOSNextDeskButtonBase() = default; + +void CrOSNextDeskButtonBase::OnFocus() { + UpdateOverviewHighlightForFocusAndSpokenFeedback(this); + UpdateFocusState(); + View::OnFocus(); +} + +void CrOSNextDeskButtonBase::OnBlur() { + UpdateFocusState(); + View::OnBlur(); +} + +views::View* CrOSNextDeskButtonBase::GetView() { + return this; +} + +void CrOSNextDeskButtonBase::MaybeActivateHighlightedView() { + pressed_callback_.Run(); +} + +void CrOSNextDeskButtonBase::MaybeCloseHighlightedView(bool primary_action) {} + +void CrOSNextDeskButtonBase::MaybeSwapHighlightedView(bool right) {} + +void CrOSNextDeskButtonBase::OnViewHighlighted() { + UpdateFocusState(); +} + +void CrOSNextDeskButtonBase::OnViewUnhighlighted() { + UpdateFocusState(); +} + +void CrOSNextDeskButtonBase::UpdateFocusState() { + views::FocusRing::Get(this)->SchedulePaint(); +} + +BEGIN_METADATA(CrOSNextDeskButtonBase, views::LabelButton) +END_METADATA + +} // namespace ash \ No newline at end of file
diff --git a/ash/wm/desks/cros_next_desk_button_base.h b/ash/wm/desks/cros_next_desk_button_base.h new file mode 100644 index 0000000..ca7da77a --- /dev/null +++ b/ash/wm/desks/cros_next_desk_button_base.h
@@ -0,0 +1,51 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WM_DESKS_CROS_NEXT_DESK_BUTTON_BASE_H_ +#define ASH_WM_DESKS_CROS_NEXT_DESK_BUTTON_BASE_H_ + +#include "ash/wm/overview/overview_highlightable_view.h" +#include "base/functional/callback_forward.h" +#include "ui/views/controls/button/label_button.h" + +namespace ash { + +// The base class of buttons (default desk button, new desk button and library +// button) on desks bar. +// TODO(conniekxu): Remove `DeskButtonBase`, replace it with this class and +// rename this class by removing the prefix CrOSNext. +class CrOSNextDeskButtonBase : public views::LabelButton, + public OverviewHighlightableView { + public: + METADATA_HEADER(CrOSNextDeskButtonBase); + + explicit CrOSNextDeskButtonBase(const std::u16string& text, + bool set_text, + base::RepeatingClosure pressed_callback); + CrOSNextDeskButtonBase(const CrOSNextDeskButtonBase&) = delete; + CrOSNextDeskButtonBase& operator=(const CrOSNextDeskButtonBase&) = delete; + ~CrOSNextDeskButtonBase() override; + + // views::LabelButton: + void OnFocus() override; + void OnBlur() override; + + // OverviewHighlightableView: + views::View* GetView() override; + void MaybeActivateHighlightedView() override; + void MaybeCloseHighlightedView(bool primary_action) override; + void MaybeSwapHighlightedView(bool right) override; + void OnViewHighlighted() override; + void OnViewUnhighlighted() override; + + protected: + virtual void UpdateFocusState(); + + private: + base::RepeatingClosure pressed_callback_; +}; + +} // namespace ash + +#endif // ASH_WM_DESKS_CROS_NEXT_DESK_BUTTON_BASE_H_ \ No newline at end of file
diff --git a/ash/wm/float/float_controller_unittest.cc b/ash/wm/float/float_controller_unittest.cc index 74653d99..9496263 100644 --- a/ash/wm/float/float_controller_unittest.cc +++ b/ash/wm/float/float_controller_unittest.cc
@@ -1294,6 +1294,35 @@ EXPECT_TRUE(WindowState::Get(window.get())->IsFloated()); } +// Tests that the tucked window is invisible while it is fully tucked. +TEST_F(TabletWindowFloatTest, TuckedWindowVisibility) { + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + std::unique_ptr<aura::Window> window = CreateFloatedWindow(); + + ui::ScopedAnimationDurationScaleMode test_duration_mode( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + // Fling to tuck the window in the bottom right. Test that the window is + // invisible once the animation is finished. + auto* float_controller = Shell::Get()->float_controller(); + FlingWindow(window.get(), /*left=*/false, /*up=*/false); + EXPECT_TRUE(window->IsVisible()); + ShellTestApi().WaitForWindowFinishAnimating(window.get()); + EXPECT_FALSE(window->IsVisible()); + ASSERT_TRUE(float_controller->IsFloatedWindowTuckedForTablet(window.get())); + + // Tests that there is an overview item created for the tucked window. + ToggleOverview(); + WaitForOverviewEnterAnimation(); + EXPECT_TRUE(GetOverviewItemForWindow(window.get())); + + // Tests that after we activate the window, the window is visible again as it + // is getting untucked. + wm::ActivateWindow(window.get()); + ShellTestApi().WaitForWindowFinishAnimating(window.get()); + EXPECT_TRUE(window->IsVisible()); +} + // Tests that the expected window gets activation after tucking a floated // window, and that on untucking the floated window, it gains activation. TEST_F(TabletWindowFloatTest, WindowActivationAfterTuckingUntucking) {
diff --git a/ash/wm/float/scoped_window_tucker.cc b/ash/wm/float/scoped_window_tucker.cc index a5aaf62..4ce5dac67 100644 --- a/ash/wm/float/scoped_window_tucker.cc +++ b/ash/wm/float/scoped_window_tucker.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/window_properties.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/scoped_animation_disabler.h" #include "ash/shell.h" #include "ash/style/color_util.h" #include "ash/style/dark_light_mode_controller_impl.h" @@ -227,6 +228,10 @@ left_ ? -kTuckOffscreenPaddingDp : kTuckOffscreenPaddingDp, 0); views::AnimationBuilder() + .OnAborted(base::BindOnce(&ScopedWindowTucker::OnAnimateTuckEnded, + weak_factory_.GetWeakPtr())) + .OnEnded(base::BindOnce(&ScopedWindowTucker::OnAnimateTuckEnded, + weak_factory_.GetWeakPtr())) .SetPreemptionStrategy( ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET) .Once() @@ -246,6 +251,9 @@ } void ScopedWindowTucker::AnimateUntuck(base::OnceClosure callback) { + ScopedAnimationDisabler disable(window_); + window_->Show(); + const gfx::RectF initial_bounds(window_->bounds()); TabletModeWindowState::UpdateWindowPosition( @@ -320,6 +328,11 @@ gfx::Tween::ACCEL_20_DECEL_100); } +void ScopedWindowTucker::OnAnimateTuckEnded() { + ScopedAnimationDisabler disable(window_); + window_->Hide(); +} + void ScopedWindowTucker::UntuckWindow() { Shell::Get()->float_controller()->MaybeUntuckFloatedWindowForTablet(window_); }
diff --git a/ash/wm/float/scoped_window_tucker.h b/ash/wm/float/scoped_window_tucker.h index 3f0bca9..8af1d288 100644 --- a/ash/wm/float/scoped_window_tucker.h +++ b/ash/wm/float/scoped_window_tucker.h
@@ -9,6 +9,7 @@ #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_observer.h" +#include "base/memory/weak_ptr.h" #include "ui/views/widget/unique_widget_ptr.h" #include "ui/wm/public/activation_change_observer.h" @@ -54,6 +55,10 @@ // overview mode respectively. void OnOverviewModeChanged(bool in_overview); + // Hides the window after the tuck animation is finished. This is so it will + // behave similarly to a minimized window in overview. + void OnAnimateTuckEnded(); + // Destroys `this_`, which will untuck `window_` and set the window bounds // back onscreen. void UntuckWindow(); @@ -75,6 +80,8 @@ base::ScopedObservation<OverviewController, OverviewObserver> overview_observer_{this}; + + base::WeakPtrFactory<ScopedWindowTucker> weak_factory_{this}; }; } // namespace ash
diff --git a/ash/wm/overview/scoped_overview_transform_window.cc b/ash/wm/overview/scoped_overview_transform_window.cc index fe18b816..4e0e8dc 100644 --- a/ash/wm/overview/scoped_overview_transform_window.cc +++ b/ash/wm/overview/scoped_overview_transform_window.cc
@@ -10,6 +10,7 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" +#include "ash/wm/float/float_controller.h" #include "ash/wm/overview/delayed_animation_observer_impl.h" #include "ash/wm/overview/overview_constants.h" #include "ash/wm/overview/overview_controller.h" @@ -508,7 +509,7 @@ } bool ScopedOverviewTransformWindow::IsMinimized() const { - return WindowState::Get(window_)->IsMinimized(); + return window_util::IsMinimizedOrTucked(window_); } void ScopedOverviewTransformWindow::PrepareForOverview() {
diff --git a/ash/wm/overview/scoped_overview_transform_window.h b/ash/wm/overview/scoped_overview_transform_window.h index 15c2878c..a66df540 100644 --- a/ash/wm/overview/scoped_overview_transform_window.h +++ b/ash/wm/overview/scoped_overview_transform_window.h
@@ -126,6 +126,8 @@ // Closes the transient root of the window managed by |this|. void Close(); + // TODO(sammiequon): Rename this function as tucked floated windows behave the + // same way as minimized windows. bool IsMinimized() const; // Ensures that a window is visible by setting its opacity to 1.
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.cc b/ash/wm/tablet_mode/tablet_mode_window_state.cc index 06fb51a..c0e1282 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_state.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_state.cc
@@ -89,8 +89,7 @@ } // Returns the maximized/full screen and/or centered bounds of a window. -gfx::Rect GetBoundsInTabletMode(WindowState* state_object, - absl::optional<float> snap_ratio) { +gfx::Rect GetBoundsInTabletMode(WindowState* state_object) { aura::Window* window = state_object->window(); if (state_object->IsFullscreen() || state_object->IsPinned()) @@ -100,14 +99,14 @@ return SplitViewController::Get(Shell::GetPrimaryRootWindow()) ->GetSnappedWindowBoundsInParent( SplitViewController::SnapPosition::kPrimary, window, - snap_ratio ? *snap_ratio : kDefaultSnapRatio); + state_object->snap_ratio().value_or(kDefaultSnapRatio)); } if (state_object->GetStateType() == WindowStateType::kSecondarySnapped) { return SplitViewController::Get(Shell::GetPrimaryRootWindow()) ->GetSnappedWindowBoundsInParent( SplitViewController::SnapPosition::kSecondary, window, - snap_ratio ? *snap_ratio : kDefaultSnapRatio); + state_object->snap_ratio().value_or(kDefaultSnapRatio)); } if (chromeos::wm::features::IsFloatWindowEnabled() && @@ -254,8 +253,7 @@ void TabletModeWindowState::UpdateWindowPosition( WindowState* window_state, WindowState::BoundsChangeAnimationType animation_type) { - const gfx::Rect bounds_in_parent = - GetBoundsInTabletMode(window_state, window_state->snap_ratio()); + const gfx::Rect bounds_in_parent = GetBoundsInTabletMode(window_state); if (bounds_in_parent == window_state->window()->GetTargetBounds()) return; @@ -311,24 +309,23 @@ break; case WM_EVENT_FULLSCREEN: UpdateWindow(window_state, WindowStateType::kFullscreen, - /*animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*animate=*/true); break; case WM_EVENT_PIN: if (!Shell::Get()->screen_pinning_controller()->IsPinned()) { UpdateWindow(window_state, WindowStateType::kPinned, - /*animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*animate=*/true); } break; case WM_EVENT_PIP: if (!window_state->IsPip()) { - UpdateWindow(window_state, WindowStateType::kPip, /*animate=*/true, - /*new_snap_ratio=*/absl::nullopt); + UpdateWindow(window_state, WindowStateType::kPip, /*animate=*/true); } break; case WM_EVENT_TRUSTED_PIN: if (!Shell::Get()->screen_pinning_controller()->IsPinned()) { UpdateWindow(window_state, WindowStateType::kTrustedPinned, - /*animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*animate=*/true); } break; case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION: @@ -339,7 +336,7 @@ case WM_EVENT_MAXIMIZE: UpdateWindow(window_state, window_state->GetMaximizedOrCenteredWindowType(), - /*animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*animate=*/true); return; case WM_EVENT_NORMAL: { // `WM_EVENT_NORMAL` may be restoring state from minimized. @@ -348,7 +345,7 @@ } else { UpdateWindow(window_state, window_state->GetMaximizedOrCenteredWindowType(), - /*animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*animate=*/true); } return; } @@ -363,13 +360,11 @@ return; UpdateWindow(window_state, WindowStateType::kFloated, - /*=animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*=animate=*/true); break; case WM_EVENT_SNAP_PRIMARY: case WM_EVENT_SNAP_SECONDARY: - // TODO(b/259302867): Remove `window_state->snap_ratio()` since it can be - // gotten from `window_state`. - DoTabletSnap(window_state, event->type(), window_state->snap_ratio()); + DoTabletSnap(window_state, event->type()); return; case WM_EVENT_CYCLE_SNAP_PRIMARY: CycleTabletSnap(window_state, @@ -381,7 +376,7 @@ return; case WM_EVENT_MINIMIZE: UpdateWindow(window_state, WindowStateType::kMinimized, - /*=animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*=animate=*/true); return; case WM_EVENT_SHOW_INACTIVE: case WM_EVENT_SYSTEM_UI_AREA_CHANGED: @@ -437,20 +432,17 @@ IsSnapped(current_state_type_) ? window_state->GetStateType() : window_state->GetMaximizedOrCenteredWindowType(); - UpdateWindow(window_state, new_state, /*animate=*/true, - /*new_snap_ratio=*/window_state->snap_ratio()); + UpdateWindow(window_state, new_state, /*animate=*/true); } break; case WM_EVENT_WORKAREA_BOUNDS_CHANGED: if (current_state_type_ != WindowStateType::kMinimized) - UpdateBounds(window_state, /*animate=*/true, - /*new_snap_ratio=*/window_state->snap_ratio()); + UpdateBounds(window_state, /*animate=*/true); break; case WM_EVENT_DISPLAY_BOUNDS_CHANGED: // Don't animate on a screen rotation - just snap to new size. if (current_state_type_ != WindowStateType::kMinimized) - UpdateBounds(window_state, /*animate=*/false, - /*new_snap_ratio=*/window_state->snap_ratio()); + UpdateBounds(window_state, /*animate=*/false); break; } } @@ -480,8 +472,8 @@ current_state_type_ != WindowStateType::kFloated && current_state_type_ != WindowStateType::kPinned && current_state_type_ != WindowStateType::kTrustedPinned) { - UpdateWindow(window_state, state_type_on_attach_, animate_bounds_on_attach_, - window_state->snap_ratio()); + UpdateWindow(window_state, state_type_on_attach_, + animate_bounds_on_attach_); } } @@ -493,8 +485,7 @@ void TabletModeWindowState::UpdateWindow(WindowState* window_state, WindowStateType target_state, - bool animated, - absl::optional<float> new_snap_ratio) { + bool animated) { aura::Window* window = window_state->window(); DCHECK(target_state == WindowStateType::kMinimized || @@ -512,7 +503,7 @@ if (target_state == WindowStateType::kMinimized) return; // If the state type did not change, update it accordingly. - UpdateBounds(window_state, animated, new_snap_ratio); + UpdateBounds(window_state, animated); return; } @@ -535,7 +526,7 @@ if (window_state->IsActive()) window_state->Deactivate(); } else { - UpdateBounds(window_state, animated, new_snap_ratio); + UpdateBounds(window_state, animated); } if ((window->layer()->GetTargetVisibility() || @@ -565,8 +556,7 @@ } void TabletModeWindowState::UpdateBounds(WindowState* window_state, - bool animated, - absl::optional<float> new_snap_ratio) { + bool animated) { // Do not update window's bounds if it's in tab-dragging process. The bounds // will be updated later when the drag ends. if (window_util::IsDraggingTabs(window_state->window())) @@ -576,8 +566,7 @@ if (current_state_type_ == WindowStateType::kMinimized) return; - gfx::Rect bounds_in_parent = - GetBoundsInTabletMode(window_state, new_snap_ratio); + gfx::Rect bounds_in_parent = GetBoundsInTabletMode(window_state); // If we have a target bounds rectangle, we center it and set it // accordingly. if (!bounds_in_parent.IsEmpty() && @@ -612,7 +601,7 @@ // If |window| is already snapped in |snap_position|, then unsnap |window|. if (window == split_view_controller->GetSnappedWindow(snap_position)) { UpdateWindow(window_state, window_state->GetMaximizedOrCenteredWindowType(), - /*animate=*/true, /*new_snap_ratio=*/absl::nullopt); + /*animate=*/true); window_state->ReadOutWindowCycleSnapAction( IDS_WM_RESTORE_SNAPPED_WINDOW_ON_SHORTCUT); return; @@ -631,8 +620,7 @@ } void TabletModeWindowState::DoTabletSnap(WindowState* window_state, - WMEventType snap_event_type, - absl::optional<float> new_snap_ratio) { + WMEventType snap_event_type) { DCHECK(snap_event_type == WM_EVENT_SNAP_PRIMARY || snap_event_type == WM_EVENT_SNAP_SECONDARY); @@ -655,7 +643,7 @@ split_view_controller->OnWMEvent(window, snap_event_type); // Change window state and bounds to the snapped window state and bounds. - UpdateWindow(window_state, new_state_type, /*animate=*/false, new_snap_ratio); + UpdateWindow(window_state, new_state_type, /*animate=*/false); } void TabletModeWindowState::DoRestore(WindowState* window_state) { @@ -663,16 +651,13 @@ if (chromeos::IsSnappedWindowStateType(restore_state)) { window_state->set_snap_action_source( WindowSnapActionSource::kSnapByWindowStateRestore); - DoTabletSnap(window_state, - restore_state == WindowStateType::kPrimarySnapped - ? WM_EVENT_SNAP_PRIMARY - : WM_EVENT_SNAP_SECONDARY, - window_state->snap_ratio()); + DoTabletSnap(window_state, restore_state == WindowStateType::kPrimarySnapped + ? WM_EVENT_SNAP_PRIMARY + : WM_EVENT_SNAP_SECONDARY); return; } - UpdateWindow(window_state, restore_state, /*animate=*/true, - /*new_snap_ratio=*/absl::nullopt); + UpdateWindow(window_state, restore_state, /*animate=*/true); } } // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_window_state.h b/ash/wm/tablet_mode/tablet_mode_window_state.h index cbf27547..21dabd8 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_state.h +++ b/ash/wm/tablet_mode/tablet_mode_window_state.h
@@ -66,12 +66,10 @@ // Updates the window to `new_state_type` and resulting bounds: // Either full screen, maximized centered or minimized. If the state does not // change, only the bounds will be changed. If `animate` is set, the bound - // change get animated. If `new_snap_ratio` is set, uses it to update snapped - // window bounds. + // change get animated. void UpdateWindow(WindowState* window_state, chromeos::WindowStateType new_state_type, - bool animate, - absl::optional<float> new_snap_ratio); + bool animate); // If `target_state` is PRIMARY/SECONDARY_SNAPPED and the window can be // snapped, returns `target_state`. Otherwise depending on the capabilities @@ -82,11 +80,8 @@ chromeos::WindowStateType target_state); // Updates the bounds to the maximum possible bounds according to the current - // window state. If `animate` is set we animate the change. If - // `new_snap_ratio` is set, uses it to update snapped window bounds. - void UpdateBounds(WindowState* window_state, - bool animate, - absl::optional<float> new_snap_ratio); + // window state. If `animate` is set we animate the change. + void UpdateBounds(WindowState* window_state, bool animate); // Handles Alt+[ if `snap_position` is // `SplitViewController::SnapPosition::kPrimary`; handles // Alt+] if @@ -95,9 +90,7 @@ SplitViewController::SnapPosition snap_position); // Snap the window in tablet split view if it can be snapped. - void DoTabletSnap(WindowState* window_state, - WMEventType snap_event_type, - absl::optional<float> new_snap_ratio); + void DoTabletSnap(WindowState* window_state, WMEventType snap_event_type); // Called by `WM_EVENT_RESTORE`, or a `WM_EVENT_NORMAL` that is restoring. // Restores to the state in `window_states`'s restore history.
diff --git a/ash/wm/window_cycle/window_cycle_controller_unittest.cc b/ash/wm/window_cycle/window_cycle_controller_unittest.cc index cc2a64a..59fe95c7 100644 --- a/ash/wm/window_cycle/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle/window_cycle_controller_unittest.cc
@@ -1968,7 +1968,7 @@ Shell::Get()->session_controller()->GetActivePrefService(); pref->SetBoolean(prefs::kNaturalScroll, false); - // Start cycle, scroll right with two finger gesture. Note: two figner swipes + // Start cycle, scroll right with two finger gesture. Note: two finger swipes // are negated, so negate in tests to mimic how this actually behaves on // devices. // Current order is [5,4,3,2,1]. @@ -2093,7 +2093,7 @@ CompleteCycling(cycle_controller); } -// Tests that when user taps tab slider buttons, but then scrolles and releases +// Tests that when user taps tab slider buttons, but then scrolls and releases // finger on a window. Mode change should not happen in this use case. TEST_F(ModeSelectionWindowCycleControllerTest, TapTabSliderButtonButReleaseOnWindow) { @@ -3698,4 +3698,89 @@ EXPECT_TRUE(wm::IsActiveWindow(w5.get())); } +// Tests that same app window cycling works in all desk mode, current desk mode, +// switching between the two modes, and switching between same app window +// cycling and normal window cycling. +TEST_F(SameAppWindowCycleControllerTest, PerDeskMode) { + // On desk 1 create 1 window of app A and 3 windows of app B. + std::unique_ptr<aura::Window> w0(CreateTestWindowWithAppID(std::string("A"))); + std::unique_ptr<aura::Window> w1(CreateTestWindowWithAppID(std::string("B"))); + std::unique_ptr<aura::Window> w2(CreateTestWindowWithAppID(std::string("B"))); + std::unique_ptr<aura::Window> w3(CreateTestWindowWithAppID(std::string("B"))); + + // On desk 2 create 2 windows of app A and 4 windows of app B. + auto* desks_controller = DesksController::Get(); + desks_controller->NewDesk(DesksCreationRemovalSource::kButton); + ASSERT_EQ(2u, desks_controller->desks().size()); + const Desk* desk_2 = desks_controller->desks()[1].get(); + ActivateDesk(desk_2); + EXPECT_EQ(desk_2, desks_controller->active_desk()); + std::unique_ptr<aura::Window> w4(CreateTestWindowWithAppID(std::string("A"))); + std::unique_ptr<aura::Window> w5(CreateTestWindowWithAppID(std::string("A"))); + std::unique_ptr<aura::Window> w6(CreateTestWindowWithAppID(std::string("B"))); + std::unique_ptr<aura::Window> w7(CreateTestWindowWithAppID(std::string("B"))); + std::unique_ptr<aura::Window> w8(CreateTestWindowWithAppID(std::string("B"))); + std::unique_ptr<aura::Window> w9(CreateTestWindowWithAppID(std::string("B"))); + + // Start cycling, all desks mode should be default so we should see 7 windows + // of app B. + auto* generator = GetEventGenerator(); + WindowCycleController* cycle_controller = + Shell::Get()->window_cycle_controller(); + generator->PressKey(ui::VKEY_MENU, ui::EF_NONE); + generator->PressAndReleaseKey(ui::VKEY_OEM_3, ui::EF_ALT_DOWN); + EXPECT_FALSE(cycle_controller->IsAltTabPerActiveDesk()); + auto cycle_windows = GetWindows(cycle_controller); + EXPECT_EQ(7u, cycle_windows.size()); + EXPECT_EQ(cycle_windows.size(), GetWindowCycleItemViews().size()); + EXPECT_TRUE(base::Contains(cycle_windows, w1.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w2.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w3.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w6.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w7.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w8.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w9.get())); + + // Select current-desk mode. We should see 4 windows of app B. + generator->MoveMouseTo( + GetWindowCycleTabSliderButtons()[1]->GetBoundsInScreen().CenterPoint()); + generator->ClickLeftButton(); + cycle_windows = GetWindows(cycle_controller); + EXPECT_EQ(4u, GetWindowCycleItemViews().size()); + EXPECT_EQ(cycle_windows.size(), GetWindowCycleItemViews().size()); + EXPECT_TRUE(base::Contains(cycle_windows, w6.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w7.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w8.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w9.get())); + generator->ReleaseKey(ui::VKEY_MENU, ui::EF_NONE); + + // Go to desk 1 and start cycling, we should still be on current-desk mode and + // see 3 windows of app B. + ActivateDesk(desks_controller->desks()[0].get()); + generator->PressKey(ui::VKEY_MENU, ui::EF_NONE); + generator->PressAndReleaseKey(ui::VKEY_OEM_3, ui::EF_ALT_DOWN); + EXPECT_TRUE(cycle_controller->IsAltTabPerActiveDesk()); + cycle_windows = GetWindows(cycle_controller); + EXPECT_EQ(3u, GetWindowCycleItemViews().size()); + EXPECT_EQ(cycle_windows.size(), GetWindowCycleItemViews().size()); + EXPECT_TRUE(base::Contains(cycle_windows, w1.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w2.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w3.get())); + generator->ReleaseKey(ui::VKEY_MENU, ui::EF_NONE); + + // Start alt tabbing. The mode selection should be shared between alt tab and + // alt backtick so we should still be on current-desk mode and see 4 windows. + generator->PressKey(ui::VKEY_MENU, ui::EF_NONE); + generator->PressAndReleaseKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); + EXPECT_TRUE(cycle_controller->IsAltTabPerActiveDesk()); + cycle_windows = GetWindows(cycle_controller); + EXPECT_EQ(4u, GetWindowCycleItemViews().size()); + EXPECT_EQ(cycle_windows.size(), GetWindowCycleItemViews().size()); + EXPECT_TRUE(base::Contains(cycle_windows, w0.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w1.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w2.get())); + EXPECT_TRUE(base::Contains(cycle_windows, w3.get())); + generator->ReleaseKey(ui::VKEY_MENU, ui::EF_NONE); +} + } // namespace ash
diff --git a/ash/wm/window_cycle/window_cycle_list.cc b/ash/wm/window_cycle/window_cycle_list.cc index e03b41c..33a88850 100644 --- a/ash/wm/window_cycle/window_cycle_list.cc +++ b/ash/wm/window_cycle/window_cycle_list.cc
@@ -91,26 +91,14 @@ } // namespace WindowCycleList::WindowCycleList(const WindowList& windows, bool same_app_only) - : windows_(windows) { + : windows_(windows), same_app_only_(same_app_only) { if (!ShouldShowUi()) Shell::Get()->mru_window_tracker()->SetIgnoreActivations(true); active_window_before_window_cycle_ = window_util::GetActiveWindow(); - if (same_app_only && windows_.size() > 1) { - WindowCycleController::WindowList same_app_window_list; - const std::string* const mru_window_app_id = - windows_.front()->GetProperty(kAppIDKey); - if (mru_window_app_id) { - windows_.erase(base::ranges::remove_if( - windows_.begin(), windows_.end(), - [&mru_window_app_id](aura::Window* window) { - const auto* const app_id = - window->GetProperty(kAppIDKey); - return !app_id || *app_id != *mru_window_app_id; - }), - windows_.end()); - } + if (same_app_only) { + MakeSameAppOnly(); } for (auto* window : windows_) @@ -175,6 +163,10 @@ RemoveAllWindows(); windows_ = windows; + if (same_app_only_) { + MakeSameAppOnly(); + } + for (auto* new_window : windows_) new_window->AddObserver(this); @@ -456,6 +448,26 @@ } } +void WindowCycleList::MakeSameAppOnly() { + DCHECK(same_app_only_); + if (windows_.size() < 2) { + return; + } + const std::string* const mru_window_app_id = + windows_.front()->GetProperty(kAppIDKey); + if (!mru_window_app_id) { + return; + } + windows_.erase( + base::ranges::remove_if(windows_.begin(), windows_.end(), + [&mru_window_app_id](aura::Window* window) { + const auto* const app_id = + window->GetProperty(kAppIDKey); + return !app_id || *app_id != *mru_window_app_id; + }), + windows_.end()); +} + int WindowCycleList::GetOffsettedWindowIndex(int offset) const { DCHECK(!windows_.empty());
diff --git a/ash/wm/window_cycle/window_cycle_list.h b/ash/wm/window_cycle/window_cycle_list.h index d5cad9d..b60b59eb 100644 --- a/ash/wm/window_cycle/window_cycle_list.h +++ b/ash/wm/window_cycle/window_cycle_list.h
@@ -134,6 +134,10 @@ // SetFocusedWindow() before this. void Scroll(int offset); + // Removes windows from `windows_` if they don't have the same app id as the + // MRU window. + void MakeSameAppOnly(); + // Returns the index for the window |offset| away from |current_index_|. Can // only be called if |windows_| is not empty. Also checks that the window for // the returned index exists. @@ -163,6 +167,9 @@ // True if one of the windows in the list has already been selected. bool window_selected_ = false; + // True if we are only cycling through windows of the same app. + const bool same_app_only_; + // The top level View for the window cycle UI. May be null if the UI is not // showing. WindowCycleView* cycle_view_ = nullptr;
diff --git a/ash/wm/window_mirror_view.cc b/ash/wm/window_mirror_view.cc index 76f6d73..67664e03 100644 --- a/ash/wm/window_mirror_view.cc +++ b/ash/wm/window_mirror_view.cc
@@ -9,6 +9,7 @@ #include "ash/wm/desks/desks_util.h" #include "ash/wm/window_state.h" +#include "ash/wm/window_util.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" #include "ui/aura/window.h" @@ -141,9 +142,9 @@ // This causes us to clip the non-client areas of the window. layer()->SetMasksToBounds(true); - // Some extra work is needed when the source window is minimized or is on an - // inactive desk. - if (WindowState::Get(source_)->IsMinimized() || + // Some extra work is needed when the source window is minimized, tucked + // offscreen or is on an inactive desk. + if (window_util::IsMinimizedOrTucked(source_) || !desks_util::BelongsToActiveDesk(source_)) { EnsureAllChildrenAreVisible(mirror_layer); }
diff --git a/ash/wm/window_util.cc b/ash/wm/window_util.cc index 8f06b056..f8496e0 100644 --- a/ash/wm/window_util.cc +++ b/ash/wm/window_util.cc
@@ -20,6 +20,7 @@ #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/shell_delegate.h" +#include "ash/wm/float/float_controller.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_session.h" @@ -402,6 +403,21 @@ return !shell->shell_delegate()->CanGoBack(window); } +bool IsMinimizedOrTucked(aura::Window* window) { + DCHECK(window->parent()); + + WindowState* window_state = WindowState::Get(window); + if (!window_state) { + return false; + } + if (window_state->IsFloated()) { + return !window->is_destroying() && + Shell::Get()->float_controller()->IsFloatedWindowTuckedForTablet( + window); + } + return window_state->IsMinimized(); +} + void SendBackKeyEvent(aura::Window* root_window) { // Send up event as well as down event as ARC++ clients expect this // sequence.
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h index c2d1978..a9c45e42 100644 --- a/ash/wm/window_util.h +++ b/ash/wm/window_util.h
@@ -128,6 +128,10 @@ // Returns whether the top window should be minimized on back action. ASH_EXPORT bool ShouldMinimizeTopWindowOnBack(); +// Returns true if `window` is in minimized state, or is in floated state and +// tucked to the side in tablet mode. +bool IsMinimizedOrTucked(aura::Window* window); + // Sends |ui::VKEY_BROWSER_BACK| key press and key release event to the // WindowTreeHost associated with |root_window|. void SendBackKeyEvent(aura::Window* root_window);
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index d272842..50be57f 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -137,6 +137,11 @@ # needs to be evaluated before enabling it there as well. init_stack_vars = !(is_android && is_official_build) + # Zero init has favorable performance/size tradeoffs for Chrome OS + # but was not evaluated for other platforms. + # TODO(adriandole) enable for both ash and lacros once lacros updates toolchain. + init_stack_vars_zero = is_chromeos_ash + # This argument is to control whether enabling text section splitting in the # final binary. When enabled, the separated text sections with prefix # '.text.hot', '.text.unlikely', '.text.startup' and '.text.exit' will not be @@ -2653,12 +2658,7 @@ config("default_init_stack_vars") { cflags = [] if (init_stack_vars && is_clang && !is_nacl && !using_sanitizer) { - if (is_chromeos && !chromeos_is_browser_only) { - # TODO(adriandole) remove chromeos_is_browser_only condition - # once lacros updates toolchain - - # Zero init has favorable performance/size tradeoffs for Chrome OS - # but was not evaluated for other platforms. + if (init_stack_vars_zero) { cflags += [ "-ftrivial-auto-var-init=zero" ] } else { cflags += [ "-ftrivial-auto-var-init=pattern" ]
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 80e2d539..84c24cce 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -11.20221222.0.1 +11.20221222.1.1
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index e25e5f1..9a6a141 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -620,14 +620,12 @@ "java/res/values-night/dimens.xml", "java/res/values-night/drawables.xml", "java/res/values-night/values.xml", - "java/res/values-sw600dp-v17/styles.xml", "java/res/values-sw600dp-v26/styles.xml", "java/res/values-sw600dp-v27/styles.xml", "java/res/values-sw600dp/dimens.xml", "java/res/values-sw600dp/drawables.xml", + "java/res/values-sw600dp/styles.xml", "java/res/values-sw600dp/values.xml", - "java/res/values-v21/styles.xml", - "java/res/values-v24/styles.xml", "java/res/values-v25/styles.xml", "java/res/values-v26/styles.xml", "java/res/values-v27/styles.xml",
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index f9bf3fcb..4c508c2 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -68,7 +68,6 @@ "java/res/layout/price_card.xml", "java/res/layout/selectable_tab_grid_card_item.xml", "java/res/layout/selectable_tab_list_card_item.xml", - "java/res/layout/store_hours_card.xml", "java/res/layout/tab_grid_card_item.xml", "java/res/layout/tab_grid_dialog_layout.xml", "java/res/layout/tab_grid_message_card_item.xml", @@ -114,7 +113,6 @@ "java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageService.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/SelectableTabGridView.java", - "java/src/org/chromium/chrome/browser/tasks/tab_management/StoreHoursCardView.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java",
diff --git a/chrome/android/features/tab_ui/java/res/layout/store_hours_card.xml b/chrome/android/features/tab_ui/java/res/layout/store_hours_card.xml deleted file mode 100644 index 9528fe7..0000000 --- a/chrome/android/features/tab_ui/java/res/layout/store_hours_card.xml +++ /dev/null
@@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2021 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<merge xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> - <LinearLayout - android:id="@+id/store_hours_box" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="4dp" - android:layout_marginStart="4dp" - android:orientation="horizontal" - android:background="@drawable/price_card_background"> - <TextView - android:id="@+id/store_hours" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="4dp" - android:layout_marginStart="10dp" - android:layout_marginEnd="4dp" - android:layout_marginBottom="4dp" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.TextMediumThick.Green.Dark" - android:textAlignment="viewStart" /> - </LinearLayout> -</merge> \ No newline at end of file
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml index a2625a0..12d323b 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
@@ -79,14 +79,6 @@ android:layout_marginStart="4dp" android:layout_marginEnd="4dp" android:visibility="gone"/> - <!-- TODO(crbug/1198288): Make decision on duplication of PriceCardView code.--> - <org.chromium.chrome.browser.tasks.tab_management.StoreHoursCardView - android:id="@+id/store_hours_box_outer" - android:layout_below="@id/tab_title" - android:background="@drawable/price_card_scrim" - android:layout_width="match_parent" - android:layout_height="56dp" - android:visibility="gone"/> <org.chromium.ui.widget.ButtonCompat android:id="@+id/create_group_button" android:layout_width="wrap_content"
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreHoursCardView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreHoursCardView.java deleted file mode 100644 index 366a2370..0000000 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreHoursCardView.java +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2021 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.tasks.tab_management; -import android.content.Context; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.widget.FrameLayout; -import android.widget.TextView; - -import org.chromium.chrome.tab_ui.R; - -/** - * Contains store opening and closing times for physical store website. - */ -public class StoreHoursCardView extends FrameLayout { - private TextView mStoreHoursBox; - public StoreHoursCardView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - /** - * Sets the store hours. - */ - public void setStoreHours(String storeHours) { - mStoreHoursBox.setText(storeHours); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - LayoutInflater.from(getContext()).inflate(R.layout.store_hours_card, this); - mStoreHoursBox = (TextView) findViewById(R.id.store_hours); - } -} \ No newline at end of file
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreTrackingUtilities.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreTrackingUtilities.java deleted file mode 100644 index c7b58093..0000000 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreTrackingUtilities.java +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2021 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.tasks.tab_management; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.price_tracking.PriceTrackingUtilities; - -/** - * A class to handle whether store hours feature is enabled. - */ -public class StoreTrackingUtilities { - /** - * @return Whether the show store hours on tabs feature is enabled. - */ - public static boolean isStoreHoursOnTabsEnabled() { - return ChromeFeatureList.sStoreHoursAndroid.isEnabled() - && !PriceTrackingUtilities.isTrackPricesOnTabsEnabled(); - } -}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index 7c405e4..2db0fb7b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -9,7 +9,6 @@ import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Matrix; -import android.text.TextUtils; import android.util.Size; import android.view.View; import android.view.ViewGroup; @@ -228,25 +227,6 @@ } }); }, false); - } else if (TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER == propertyKey) { - StoreHoursCardView storeHoursCardView = - (StoreHoursCardView) view.fastFindViewById(R.id.store_hours_box_outer); - if (model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER) != null) { - model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER) - .fetch((storePersistedTabData) -> { - if (storePersistedTabData == null - || TextUtils.isEmpty( - storePersistedTabData.getStoreHoursString())) { - storeHoursCardView.setVisibility(View.GONE); - } else { - storeHoursCardView.setStoreHours( - storePersistedTabData.getStoreHoursString()); - storeHoursCardView.setVisibility(View.VISIBLE); - } - }); - } else { - storeHoursCardView.setVisibility(View.GONE); - } } else if (TabProperties.SHOULD_SHOW_PRICE_DROP_TOOLTIP == propertyKey) { if (model.get(TabProperties.SHOULD_SHOW_PRICE_DROP_TOOLTIP)) { PriceCardView priceCardView =
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index e333a78..e0b42f7 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -55,7 +55,6 @@ import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.state.CouponPersistedTabData; import org.chromium.chrome.browser.tab.state.ShoppingPersistedTabData; -import org.chromium.chrome.browser.tab.state.StorePersistedTabData; import org.chromium.chrome.browser.tabmodel.EmptyTabModelFilter; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -223,28 +222,6 @@ } /** - * Provides capability to asynchronously acquire {@link StorePersistedTabData} - */ - static class StorePersistedTabDataFetcher { - protected Tab mTab; - - /** - * @param tab {@link Tab} {@link StorePersistedTabData} will be acquired for. - */ - StorePersistedTabDataFetcher(Tab tab) { - mTab = tab; - } - - /** - * Asynchronously acquire {@link StorePersistedTabData} - * @param callback {@link Callback} to pass {@link StorePersistedTabData} back in - */ - public void fetch(Callback<StorePersistedTabData> callback) { - StorePersistedTabData.from(mTab, (res) -> { callback.onResult(res); }); - } - } - - /** * Asynchronously acquire {@link CouponPersistedTabData} */ static class CouponPersistedTabDataFetcher { @@ -1827,13 +1804,6 @@ mModel.get(index).model.set( TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER, null); } - if (StoreTrackingUtilities.isStoreHoursOnTabsEnabled() - && isUngroupedTab(pseudoTab.getId())) { - mModel.get(index).model.set(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER, - new StorePersistedTabDataFetcher(pseudoTab.getTab())); - } else { - mModel.get(index).model.set(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER, null); - } if (CouponUtilities.isCouponsOnTabsEnabled() && isUngroupedTab(pseudoTab.getId())) { mModel.get(index).model.set(TabProperties.COUPON_PERSISTED_TAB_DATA_FETCHER, new CouponPersistedTabDataFetcher(pseudoTab.getTab())); @@ -1843,7 +1813,6 @@ } else { mModel.get(index).model.set(TabProperties.COUPON_PERSISTED_TAB_DATA_FETCHER, null); mModel.get(index).model.set(TabProperties.SHOPPING_PERSISTED_TAB_DATA_FETCHER, null); - mModel.get(index).model.set(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER, null); } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java index 38d7209..5c73bfc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java
@@ -107,9 +107,6 @@ public static final WritableObjectPropertyKey<TabListMediator.ShoppingPersistedTabDataFetcher> SHOPPING_PERSISTED_TAB_DATA_FETCHER = new WritableObjectPropertyKey<>(true); - public static final WritableObjectPropertyKey<TabListMediator.StorePersistedTabDataFetcher> - STORE_PERSISTED_TAB_DATA_FETCHER = new WritableObjectPropertyKey<>(true); - public static final WritableObjectPropertyKey<TabListMediator.CouponPersistedTabDataFetcher> COUPON_PERSISTED_TAB_DATA_FETCHER = new WritableObjectPropertyKey<>(true); @@ -129,8 +126,8 @@ TABSTRIP_FAVICON_BACKGROUND_COLOR_ID, SELECTABLE_TAB_ACTION_BUTTON_BACKGROUND, SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND, URL_DOMAIN, ACCESSIBILITY_DELEGATE, CARD_TYPE, CONTENT_DESCRIPTION_STRING, CLOSE_BUTTON_DESCRIPTION_STRING, - SHOPPING_PERSISTED_TAB_DATA_FETCHER, STORE_PERSISTED_TAB_DATA_FETCHER, - COUPON_PERSISTED_TAB_DATA_FETCHER, SHOULD_SHOW_PRICE_DROP_TOOLTIP}; + SHOPPING_PERSISTED_TAB_DATA_FETCHER, COUPON_PERSISTED_TAB_DATA_FETCHER, + SHOULD_SHOW_PRICE_DROP_TOOLTIP}; public static final PropertyKey[] ALL_KEYS_TAB_STRIP = new PropertyKey[] {TAB_ID, TAB_SELECTED_LISTENER, TAB_CLOSED_LISTENER, FAVICON,
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index 62da69c..a518f6db 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -1424,71 +1424,6 @@ setUpForTabGroupOperation(TabListMediatorType.TAB_SWITCHER, TabListMode.GRID); } - @Test - public void testStoreHoursFetcherActiveForForUngroupedTabs() { - prepareForStoreHours(); - resetWithRegularTabs(false); - - assertThat(mModel.size(), equalTo(2)); - assertThat(mModel.get(0).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER), - instanceOf(TabListMediator.StorePersistedTabDataFetcher.class)); - assertThat(mModel.get(1).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER), - instanceOf(TabListMediator.StorePersistedTabDataFetcher.class)); - } - - @Test - public void testStoreHoursFetcherInactiveForForGroupedTabs() { - prepareForStoreHours(); - resetWithRegularTabs(true); - - assertThat(mModel.size(), equalTo(2)); - assertNull(mModel.get(0).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER)); - assertNull(mModel.get(1).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER)); - } - - @Test - public void testStoreHoursFetcherGroupedThenUngrouped() { - prepareForStoreHours(); - resetWithRegularTabs(true); - - assertThat(mModel.size(), equalTo(2)); - assertNull(mModel.get(0).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER)); - assertNull(mModel.get(1).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER)); - resetWithRegularTabs(false); - assertThat(mModel.size(), equalTo(2)); - assertThat(mModel.get(0).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER), - instanceOf(TabListMediator.StorePersistedTabDataFetcher.class)); - assertThat(mModel.get(1).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER), - instanceOf(TabListMediator.StorePersistedTabDataFetcher.class)); - } - - @Test - public void testStoreHoursFetcherUngroupedThenGrouped() { - prepareForStoreHours(); - resetWithRegularTabs(false); - - assertThat(mModel.size(), equalTo(2)); - assertThat(mModel.get(0).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER), - instanceOf(TabListMediator.StorePersistedTabDataFetcher.class)); - assertThat(mModel.get(1).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER), - instanceOf(TabListMediator.StorePersistedTabDataFetcher.class)); - resetWithRegularTabs(true); - assertThat(mModel.size(), equalTo(2)); - assertNull(mModel.get(0).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER)); - assertNull(mModel.get(1).model.get(TabProperties.STORE_PERSISTED_TAB_DATA_FETCHER)); - } - - /** - * Set flags and initialize for verifying store hours behavior - */ - private void prepareForStoreHours() { - ChromeFeatureList.sStoreHoursAndroid.setForTesting(true); - PriceTrackingFeatures.setIsSignedInAndSyncEnabledForTesting(true); - PersistedTabDataConfiguration.setUseTestConfig(true); - initAndAssertAllProperties(); - setUpForTabGroupOperation(TabListMediatorType.TAB_SWITCHER, TabListMode.GRID); - } - /** * Reset mediator with non-incognito tabs which are optionally grouped * @param isGrouped true if the tabs should be grouped
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni index e6dff07..7df1d2c 100644 --- a/chrome/android/features/tab_ui/tab_management_java_sources.gni +++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -7,7 +7,6 @@ "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/TabAttributeCache.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialog.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/CouponUtilities.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StoreTrackingUtilities.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java",
diff --git a/chrome/android/java/res/values-sw600dp-v17/styles.xml b/chrome/android/java/res/values-sw600dp/styles.xml similarity index 100% rename from chrome/android/java/res/values-sw600dp-v17/styles.xml rename to chrome/android/java/res/values-sw600dp/styles.xml
diff --git a/chrome/android/java/res/values-v21/styles.xml b/chrome/android/java/res/values-v21/styles.xml deleted file mode 100644 index 87fcd92..0000000 --- a/chrome/android/java/res/values-v21/styles.xml +++ /dev/null
@@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2014 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources> - <style name="NavigationPopupDialog" parent="Widget.AppCompat.Light.ListPopupWindow"> - <item name="android:popupElevation">0dp</item> - </style> - - <style name="Base.V21.Theme.Chromium" parent="Base.V17.Theme.Chromium"> - <!-- Set android alert dialog attributes because the context menu dialog is - OS-dependent. Not setting alertDialogTheme pre-v21 because the window background - causes bad visual states with alert dialog list. --> - <item name="android:alertDialogTheme">@style/ThemeOverlay.BrowserUI.AlertDialog</item> - </style> - <style name="Base.Theme.Chromium" parent="Base.V21.Theme.Chromium" /> - - <!-- Theme variation for low-end devices. - - Since ChromeActivities are not HW accelerated, they don't get fancy - material shadows for popups. This theme sets drawable with pre-baked - shadows to those popups to make them look better. - '*_bg_tinted' are a 9-patchs similar to 'abc_popup_background_mtrl_mult' - drawable from Android support library, where it's used to simulate - material design on earlier Android versions. - --> - <style name="ListPopupWindow.LowEnd" parent="android:Widget.Material.Light.ListPopupWindow"> - <item name="android:popupBackground">@drawable/menu_bg_tinted</item> - </style> - <style name="Spinner.LowEnd" parent="android:Widget.Material.Light.Spinner"> - <item name="android:popupBackground">@drawable/dialog_bg_tinted</item> - </style> - <style name="AutoCompleteTextView.LowEnd" parent="android:Widget.Material.Light.AutoCompleteTextView"> - <item name="android:popupBackground">@drawable/menu_bg_tinted</item> - </style> - <style name="Theme.Chromium.WithWindowAnimation.LowEnd" - parent="Theme.Chromium.WithWindowAnimation"> - <item name="android:popupWindowStyle">@style/ListPopupWindow.LowEnd</item> - <item name="android:listPopupWindowStyle">@style/ListPopupWindow.LowEnd</item> - <item name="android:spinnerStyle">@style/Spinner.LowEnd</item> - <item name="android:autoCompleteTextViewStyle">@style/AutoCompleteTextView.LowEnd</item> - - <!-- Without HW acceleration the default text cursor looks weird (top - half is way brighter than the bottom), so we use our own. --> - <item name="android:textCursorDrawable">@drawable/text_cursor_lowend</item> - </style> - - <!-- Match the fontFamily in ui/android/java/res/values-v21/styles.xml --> - <style name="TextAppearance.FreFirstFrameButton" parent="TextAppearance.Button.Text.Filled"> - <item name="android:fontFamily">sans-serif-medium</item> - </style> - </resources>
diff --git a/chrome/android/java/res/values-v24/styles.xml b/chrome/android/java/res/values-v24/styles.xml deleted file mode 100644 index 7d495bf1..0000000 --- a/chrome/android/java/res/values-v24/styles.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2016 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- On Android N, if the ChromeLauncherActivity is NoDisplay then - intents are not always immediately sent when Chrome is docked to - the top of the screen in multi-window mode. Use Translucent.NoTitleBar - for the theme instead. See crbug.com/645074. --> - <style name="LauncherTheme" parent="Theme.BrowserUI.Translucent.NoTitleBar" /> -</resources>
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml index 065f03a..2acd008 100644 --- a/chrome/android/java/res/values/styles.xml +++ b/chrome/android/java/res/values/styles.xml
@@ -8,10 +8,18 @@ <resources xmlns:tools="http://schemas.android.com/tools"> <!-- TODO(huayinz): Move themes to another xml file. --> <!-- Application themes --> - <style name="LauncherTheme" parent="Theme.BrowserUI.NoDisplay" /> + <!-- On Android N, if the ChromeLauncherActivity is NoDisplay then + intents are not always immediately sent when Chrome is docked to + the top of the screen in multi-window mode. Use Translucent.NoTitleBar + for the theme instead. See crbug.com/645074. --> + <style name="LauncherTheme" parent="Theme.BrowserUI.Translucent.NoTitleBar" /> - <style name="Base.V17.Theme.Chromium" parent="Theme.BrowserUI.DayNight" /> - <style name="Base.Theme.Chromium" parent="Base.V17.Theme.Chromium" /> + <style name="Base.V21.Theme.Chromium" parent="Theme.BrowserUI.DayNight"> + <!-- Set android alert dialog attributes because the context menu dialog is + OS-dependent. --> + <item name="android:alertDialogTheme">@style/ThemeOverlay.BrowserUI.AlertDialog</item> + </style> + <style name="Base.Theme.Chromium" parent="Base.V21.Theme.Chromium" /> <style name="Base.Theme.Chromium.WithWindowAnimation"> <item name="android:windowContentOverlay">@null</item> @@ -130,6 +138,37 @@ <item name="android:windowLightNavigationBar" tools:targetApi="28">false</item> </style> + <!-- Theme variation for low-end devices. + + Since ChromeActivities are not HW accelerated, they don't get fancy + material shadows for popups. This theme sets drawable with pre-baked + shadows to those popups to make them look better. + '*_bg_tinted' are a 9-patchs similar to 'abc_popup_background_mtrl_mult' + drawable from Android support library, where it's used to simulate + material design on earlier Android versions. + --> + <style name="ListPopupWindow.LowEnd" parent="android:Widget.Material.Light.ListPopupWindow"> + <item name="android:popupBackground">@drawable/menu_bg_tinted</item> + </style> + <style name="Spinner.LowEnd" parent="android:Widget.Material.Light.Spinner"> + <item name="android:popupBackground">@drawable/dialog_bg_tinted</item> + </style> + <style name="AutoCompleteTextView.LowEnd" parent="android:Widget.Material.Light.AutoCompleteTextView"> + <item name="android:popupBackground">@drawable/menu_bg_tinted</item> + </style> + <style name="Theme.Chromium.WithWindowAnimation.LowEnd" + parent="Theme.Chromium.WithWindowAnimation"> + <item name="android:popupWindowStyle">@style/ListPopupWindow.LowEnd</item> + <item name="android:listPopupWindowStyle">@style/ListPopupWindow.LowEnd</item> + <item name="android:spinnerStyle">@style/Spinner.LowEnd</item> + <item name="android:autoCompleteTextViewStyle">@style/AutoCompleteTextView.LowEnd</item> + + <!-- Without HW acceleration the default text cursor looks weird (top + half is way brighter than the bottom), so we use our own. --> + <item name="android:textCursorDrawable">@drawable/text_cursor_lowend</item> + </style> + + <!-- Settings --> <style name="SettingsToolbarStyle" parent="Widget.MaterialComponents.Toolbar"> <item name="titleTextAppearance">@style/TextAppearance.Headline.Primary</item> @@ -198,8 +237,9 @@ <style name="TextAppearance.FreFirstFrameTitle" parent="TextAppearance.Headline.Primary" > <item name="android:fontFamily">sans-serif</item> </style> + <!-- Match the fontFamily in ui/android/java/res/values/styles.xml --> <style name="TextAppearance.FreFirstFrameButton" parent="TextAppearance.Button.Text.Filled"> - <item name="android:fontFamily">sans-serif</item> + <item name="android:fontFamily">sans-serif-medium</item> </style> <style name="FreTitle"> <item name="android:layout_width">wrap_content</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashController.java index 7729b3a..429704a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashController.java
@@ -6,7 +6,6 @@ import android.app.Activity; import android.graphics.PixelFormat; -import android.os.Build; import android.os.SystemClock; import android.view.View; import android.view.ViewGroup; @@ -283,8 +282,7 @@ // we also see visual glitches in the following cases: // - closing activity (example: https://crbug.com/856544#c41) // - send activity to the background (example: https://crbug.com/856544#c30) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - && ChromeFeatureList.sSwapPixelFormatToFixConvertFromTranslucent.isEnabled()) { + if (ChromeFeatureList.sSwapPixelFormatToFixConvertFromTranslucent.isEnabled()) { return TranslucencyRemoval.ON_SPLASH_HIDDEN; } return TranslucencyRemoval.ON_SPLASH_SHOWN;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 351e3d2..913cd8ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -286,7 +286,6 @@ @Override public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return null; View activeView = getContentView(); if (activeView == null || !ViewCompat.isAttachedToWindow(activeView)) return null; return ApiHelperForN.onResolvePointerIcon(activeView, event, pointerIndex);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/datareduction/DataSaverOSSetting.java b/chrome/android/java/src/org/chromium/chrome/browser/datareduction/DataSaverOSSetting.java index 172973ab..ada82f5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/datareduction/DataSaverOSSetting.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/datareduction/DataSaverOSSetting.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.net.ConnectivityManager; -import android.os.Build; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; @@ -23,7 +22,7 @@ Context context = ContextUtils.getApplicationContext(); ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (connMgr.isActiveNetworkMetered() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (connMgr.isActiveNetworkMetered()) { return ApiHelperForN.getRestrictBackgroundStatus(connMgr) == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java index de91a6c..b6a9414 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java
@@ -7,7 +7,6 @@ import android.app.Notification; import android.app.NotificationManager; import android.content.Context; -import android.os.Build; import org.chromium.base.ContextUtils; import org.chromium.chrome.R; @@ -38,9 +37,8 @@ // From Android N, notification by default has the app name and title should not be the same // as app name. - String title = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? context.getResources().getString(R.string.close_all_incognito_notification_title) - : context.getResources().getString(R.string.app_name); + String title = + context.getResources().getString(R.string.close_all_incognito_notification_title); NotificationWrapperBuilder builder = NotificationWrapperBuilderFactory
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java index ac87ade0..235072ba 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.init; import android.app.Activity; -import android.os.Build; import android.os.Process; import android.os.StrictMode; @@ -199,15 +198,10 @@ * Running in an AsyncTask as pre-loading itself may cause I/O. */ private void warmUpSharedPrefs() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> { - DownloadManagerService.warmUpSharedPrefs(); - BackgroundTaskSchedulerFactory.warmUpSharedPrefs(); - }); - } else { + PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> { DownloadManagerService.warmUpSharedPrefs(); BackgroundTaskSchedulerFactory.warmUpSharedPrefs(); - } + }); } private void preInflationStartup() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java index f9871e1..c2e26225 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java
@@ -15,7 +15,6 @@ import android.graphics.BitmapFactory; import android.graphics.Color; import android.net.Uri; -import android.os.Build; import android.provider.Browser; import android.text.TextUtils; @@ -274,9 +273,6 @@ private static boolean willExposeFileUri(Uri uri) { assert uri != null && !uri.equals(Uri.EMPTY) : "URI is not successfully generated."; - - // On Android N and later, an Exception is thrown if we try to expose a file:// URI. - return uri.getScheme().equals(ContentResolver.SCHEME_FILE) - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; + return uri.getScheme().equals(ContentResolver.SCHEME_FILE); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index d4d86f1d..61fc6090 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -10,7 +10,6 @@ import android.graphics.BitmapFactory; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; -import android.os.Build; import android.text.TextUtils; import android.util.ArrayMap; import android.util.LruCache; @@ -954,8 +953,6 @@ * Retrieves the user's preferred locale from the app's configurations. */ private Locale getPreferredLocale() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? mActivity.getResources().getConfiguration().getLocales().get(0) - : mActivity.getResources().getConfiguration().locale; + return mActivity.getResources().getConfiguration().getLocales().get(0); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java index 9ce821b..b976387 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageArchivePublisherBridge.java
@@ -14,7 +14,6 @@ import android.provider.MediaStore.MediaColumns; import android.text.format.DateUtils; -import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; import org.chromium.base.ContentUriUtils; @@ -69,11 +68,6 @@ public static long addCompletedDownload(String title, String description, String path, long length, String uri, String referer) { try { - // Call the proper version of the pass through based on the supported API level. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - return callAddCompletedDownload(title, description, path, length); - } - return callAddCompletedDownload(title, description, path, length, uri, referer); } catch (Exception e) { // In case of exception, we return a download id of 0. @@ -82,18 +76,6 @@ } } - // Use this pass through before API level 24. - private static long callAddCompletedDownload( - String title, String description, String path, long length) { - DownloadManager downloadManager = getDownloadManager(); - if (downloadManager == null) return 0; - - return downloadManager.addCompletedDownload(title, description, IS_MEDIA_SCANNER_SCANNABLE, - MIME_TYPE, path, length, SHOW_NOTIFICATION); - } - - // Use this pass through for API levels 24 and higher. - @RequiresApi(Build.VERSION_CODES.N) private static long callAddCompletedDownload(String title, String description, String path, long length, String uri, String referer) { DownloadManager downloadManager = getDownloadManager();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerServiceImpl.java index e0cedef..73a22d0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerServiceImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerServiceImpl.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.Bundle; import android.text.TextUtils; @@ -193,12 +192,6 @@ return; } - // Dispatch message immediately on pre N versions of Android. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - dispatchMessageToDriver(message); - return; - } - // Check if we should bypass the scheduler for high priority messages. if (!maybeBypassScheduler(message)) { scheduleBackgroundTask(message);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundServiceImpl.java index 9de3837..6d3f4eb3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundServiceImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundServiceImpl.java
@@ -5,11 +5,8 @@ package org.chromium.chrome.browser.services.gcm; import android.content.Intent; -import android.os.Build; import android.os.Bundle; -import androidx.annotation.RequiresApi; - import org.chromium.base.Log; import org.chromium.base.task.PostTask; import org.chromium.components.gcm_driver.GCMMessage; @@ -20,7 +17,6 @@ * if we received a high priority push message, as that should allow us to start a background * service even if Chrome is not running. */ -@RequiresApi(Build.VERSION_CODES.N) public class GCMBackgroundServiceImpl extends GCMBackgroundService.Impl { private static final String TAG = "GCMBackgroundService";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundTask.java index 33dc0b2..23258aca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GCMBackgroundTask.java
@@ -5,11 +5,9 @@ package org.chromium.chrome.browser.services.gcm; import android.content.Context; -import android.os.Build; import android.os.Bundle; import androidx.annotation.MainThread; -import androidx.annotation.RequiresApi; import org.chromium.base.Log; import org.chromium.components.background_task_scheduler.BackgroundTask; @@ -20,7 +18,6 @@ * Processes jobs that have been scheduled for delivering GCM messages to the native GCM Driver, * processing for which may exceed the lifetime of the GcmListenerService. */ -@RequiresApi(Build.VERSION_CODES.N) public class GCMBackgroundTask implements BackgroundTask { private static final String TAG = "GCMBackgroundTask";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java index b3c5630..d4f57d0f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java
@@ -210,9 +210,7 @@ return; } mIsInOverviewMode = true; - if (!OmniboxFeatures.shouldMatchToolbarAndStatusBarColor()) { - updateStatusBarColor(); - } + updateStatusBarColor(); } @Override @@ -286,6 +284,7 @@ } // StatusIndicatorCoordinator.StatusIndicatorObserver implementation. + @Override public void onStatusIndicatorColorChanged(@ColorInt int newColor) { mStatusIndicatorColor = newColor; @@ -381,12 +380,6 @@ // Return status bar color in overview mode. if (mIsInOverviewMode) { - // Toolbar will notify status bar color controller about the toolbar color during - // overview animation. - if (OmniboxFeatures.shouldMatchToolbarAndStatusBarColor()) { - return mToolbarColor; - } - return (mIsIncognito && ToolbarColors.canUseIncognitoToolbarThemeColorInOverview( mWindow.getContext()))
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java index 1b023056..e1d4646 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java
@@ -338,8 +338,7 @@ } boolean isSplashProvidedByWebApk = - (canUseSplashFromContentProvider && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - && hasContentProviderForSplash(webApkPackageName)); + (canUseSplashFromContentProvider && hasContentProviderForSplash(webApkPackageName)); return create(intent, url, scope, new WebappIcon(webApkPackageName,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index e1fcc94f..becc710 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -43,7 +43,6 @@ import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MaxAndroidSdkLevel; -import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.R; @@ -895,7 +894,6 @@ @LargeTest @Feature({"ContextualSearch"}) @CommandLineFlags.Add(ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING) - @MinAndroidSdkLevel(Build.VERSION_CODES.N) @MaxAndroidSdkLevel(value = Build.VERSION_CODES.R, reason = "crbug.com/1301017") @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class) public void testTabReparenting(@EnabledFeature int enabledFeature) throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTriggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTriggerTest.java index 06a1aff..8b2b5237 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTriggerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTriggerTest.java
@@ -6,7 +6,6 @@ import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE; -import android.os.Build; import android.text.TextUtils; import android.view.ViewConfiguration; @@ -22,7 +21,6 @@ import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; @@ -148,8 +146,7 @@ * Tests that a Tap gesture followed by scrolling clears the selection. */ @Test - @DisableIf. - Build(sdk_is_greater_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/841017") + @DisabledTest(message = "crbug.com/841017") @SmallTest @Feature({"ContextualSearch"}) public void testTapGestureFollowedByScrollClearsSelection() throws Exception { @@ -256,11 +253,9 @@ @SmallTest @Feature({"ContextualSearch"}) @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class) - @DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.M, - message = "crbug.com/1071080, crbug.com/1362185") - public void - testLongPressGestureFollowedByScrollMaintainsSelection(@EnabledFeature int enabledFeature) - throws Exception { + @DisabledTest(message = "crbug.com/1071080, crbug.com/1362185") + public void testLongPressGestureFollowedByScrollMaintainsSelection( + @EnabledFeature int enabledFeature) throws Exception { longPressNode("intelligence"); waitForPanelToPeek(); scrollBasePage();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java index 99ee0b4..91ef262 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java
@@ -389,7 +389,8 @@ "ToolbarLayout should be of type ToolbarPhone to get and check toolbar background.", toolbar instanceof ToolbarPhone); - final int toolbarColor = ((ToolbarPhone) toolbar).getToolbarBackgroundColor(); + final int toolbarColor = + ((ToolbarPhone) toolbar).getToolbarBackgroundColorForTesting(activity); CriteriaHelper.pollUiThread(() -> { Criteria.checkThat(activity.getWindow().getStatusBarColor(), Matchers.is(toolbarColor)); }, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerNotificationTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerNotificationTest.java index b5b35b4..34758ec2 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerNotificationTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerNotificationTest.java
@@ -26,8 +26,6 @@ import org.robolectric.shadows.ShadowNotification; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.R; -import org.chromium.components.browser_ui.media.MediaNotificationController; import org.chromium.components.browser_ui.media.MediaNotificationInfo; import org.chromium.services.media_session.MediaMetadata; import org.chromium.services.media_session.MediaPosition; @@ -43,62 +41,7 @@ sdk = Build.VERSION_CODES.N_MR1, shadows = MediaNotificationTestShadowResources.class) public class MediaNotificationManagerNotificationTest extends MediaNotificationTestBase { @Test - public void updateNotificationBuilderDisplaysCorrectMetadata_PreN_NonEmptyArtistAndAlbum() { - MediaNotificationController.sOverrideIsRunningNForTesting = false; - - mMediaNotificationInfoBuilder.setMetadata(new MediaMetadata("title", "artist", "album")); - mMediaNotificationInfoBuilder.setOrigin("https://example.com/"); - - MediaNotificationInfo info = mMediaNotificationInfoBuilder.build(); - Notification notification = updateNotificationBuilderAndBuild(info); - - ShadowNotification shadowNotification = Shadows.shadowOf(notification); - - if (info.isPrivate) { - assertNotEquals("title", shadowNotification.getContentTitle()); - assertNotEquals("artist - album", shadowNotification.getContentText()); - if (hasNApis()) { - assertNull(notification.extras.getString(Notification.EXTRA_SUB_TEXT)); - } - } else { - assertEquals("title", shadowNotification.getContentTitle()); - assertEquals("artist - album", shadowNotification.getContentText()); - - if (hasNApis()) { - assertEquals("https://example.com/", - notification.extras.getString(Notification.EXTRA_SUB_TEXT)); - } - } - } - - @Test - public void updateNotificationBuilderDisplaysCorrectMetadata_PreN_EmptyArtistAndAlbum() { - MediaNotificationController.sOverrideIsRunningNForTesting = false; - - mMediaNotificationInfoBuilder.setMetadata(new MediaMetadata("title", "", "")); - mMediaNotificationInfoBuilder.setOrigin("https://example.com/"); - - MediaNotificationInfo info = mMediaNotificationInfoBuilder.build(); - Notification notification = updateNotificationBuilderAndBuild(info); - - ShadowNotification shadowNotification = Shadows.shadowOf(notification); - - if (info.isPrivate) { - assertNotEquals(info.metadata.getTitle(), shadowNotification.getContentTitle()); - assertNotNull(shadowNotification.getContentText()); - } else { - assertEquals(info.metadata.getTitle(), shadowNotification.getContentTitle()); - assertEquals(info.origin, shadowNotification.getContentText()); - } - if (hasNApis()) { - assertEquals(null, notification.extras.getString(Notification.EXTRA_SUB_TEXT)); - } - } - - @Test - public void updateNotificationBuilderDisplaysCorrectMetadata_AtLeastN_EmptyArtistAndAlbum() { - MediaNotificationController.sOverrideIsRunningNForTesting = true; - + public void updateNotificationBuilderDisplaysCorrectMetadata_EmptyArtistAndAlbum() { mMediaNotificationInfoBuilder.setMetadata(new MediaMetadata("title", "", "")); mMediaNotificationInfoBuilder.setOrigin("https://example.com/"); @@ -155,26 +98,6 @@ } @Test - public void updateNotificationBuilderDisplaysCorrectLargeIcon_WithoutLargeIcon_PreN() { - MediaNotificationController.sOverrideIsRunningNForTesting = false; - assertNull(getController().mDefaultNotificationLargeIcon); - - mMediaNotificationInfoBuilder.setNotificationLargeIcon(null); - - MediaNotificationInfo info = - mMediaNotificationInfoBuilder - .setDefaultNotificationLargeIcon(R.drawable.audio_playing_square) - .build(); - Notification notification = updateNotificationBuilderAndBuild(info); - - assertNotNull(getController().mDefaultNotificationLargeIcon); - if (hasNApis()) { - assertTrue(getController().mDefaultNotificationLargeIcon.sameAs( - iconToBitmap(notification.getLargeIcon()))); - } - } - - @Test public void updateNotificationBuilderDisplaysCorrectLargeIcon_DontSupportPlayPause() { Bitmap largeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); mMediaNotificationInfoBuilder.setNotificationLargeIcon(largeIcon).setActions(0);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java index db8fe61..a00b552 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java
@@ -575,7 +575,7 @@ -> false, /*logoClickedCallback=*/null, /*isRefactorEnabled=*/false, /*shouldFetchDoodle=*/false, shouldCreateLogoInToolbar, - mFinishedShowingCallback, null); + mFinishedShowingCallback); mMediator.onLogoViewReady(mLogoView); mMediator.initLogoWithNative();
diff --git a/chrome/app/app-Info.plist b/chrome/app/app-Info.plist index ba0f3008..ff644f1 100644 --- a/chrome/app/app-Info.plist +++ b/chrome/app/app-Info.plist
@@ -257,9 +257,10 @@ <key>UTTypeConformsTo</key> <array> <string>public.data</string> + <string>public.content</string> </array> <key>UTTypeDescription</key> - <string>Chromium Extra</string> + <string>Chromium Extension</string> <key>UTTypeIdentifier</key> <string>org.chromium.extension</string> <key>UTTypeTagSpecification</key> @@ -268,6 +269,10 @@ <array> <string>crx</string> </array> + <key>public.mime-type</key> + <array> + <string>application/x-chrome-extension</string> + </array> </dict> </dict> </array> @@ -277,6 +282,7 @@ <key>UTTypeConformsTo</key> <array> <string>public.data</string> + <string>public.content</string> </array> <key>UTTypeDescription</key> <string>MIME HTML document</string> @@ -284,6 +290,8 @@ <string>document.icns</string> <key>UTTypeIdentifier</key> <string>org.ietf.mhtml</string> + <key>UTTypeReferenceURL</key> + <string>https://www.ietf.org/rfc/rfc2557</string> <key>UTTypeTagSpecification</key> <dict> <key>com.apple.ostype</key> @@ -293,6 +301,11 @@ <string>mht</string> <string>mhtml</string> </array> + <key>public.mime-type</key> + <array> + <string>multipart/related</string> + <string>application/x-mimearchive</string> + </array> </dict> </dict> <dict> @@ -307,7 +320,7 @@ <key>UTTypeIdentifier</key> <string>org.xiph.ogg-audio</string> <key>UTTypeReferenceURL</key> - <string>http://xiph.org/ogg</string> + <string>https://xiph.org/ogg/</string> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> @@ -315,6 +328,10 @@ <string>ogg</string> <string>oga</string> </array> + <key>public.mime-type</key> + <array> + <string>audio/ogg</string> + </array> </dict> </dict> <dict> @@ -329,7 +346,7 @@ <key>UTTypeIdentifier</key> <string>org.xiph.ogv</string> <key>UTTypeReferenceURL</key> - <string>http://xiph.org/ogg</string> + <string>https://xiph.org/ogg/</string> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> @@ -337,6 +354,10 @@ <string>ogm</string> <string>ogv</string> </array> + <key>public.mime-type</key> + <array> + <string>video/ogg</string> + </array> </dict> </dict> <dict> @@ -345,7 +366,7 @@ <string>public.movie</string> </array> <key>UTTypeDescription</key> - <string>HTML5 Video (WebM)</string> + <string>WebM media</string> <key>UTTypeIconFile</key> <string>document.icns</string> <key>UTTypeIdentifier</key> @@ -358,6 +379,11 @@ <array> <string>webm</string> </array> + <key>public.mime-type</key> + <array> + <string>video/webm</string> + <string>audio/webm</string> + </array> </dict> </dict> <dict> @@ -379,6 +405,10 @@ <array> <string>webp</string> </array> + <key>public.mime-type</key> + <array> + <string>image/webp</string> + </array> </dict> </dict> </array>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index cdc2630..75730da 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -9520,10 +9520,6 @@ desc="Button text for the Screenshot dialog edit button."> Edit </message> - <message name="IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_SEARCH_IMAGE_BUTTON_LABEL" - desc="Button text for the Screenshot dialog search image button."> - Search with Google - </message> <message name="IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_SHARE_BUTTON_LABEL" desc="Button text for the Screenshot dialog share button."> Share
diff --git a/chrome/app/generated_resources_grd/IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_SEARCH_IMAGE_BUTTON_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_SEARCH_IMAGE_BUTTON_LABEL.png.sha1 deleted file mode 100644 index 6aa7e3ab..0000000 --- a/chrome/app/generated_resources_grd/IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_SEARCH_IMAGE_BUTTON_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -193406ee37dbba1ac00127dd327151c847b41672 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 24dd75c..dca4d11 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -4402,7 +4402,7 @@ When turned on, all notifications will be silenced </message> <message name="IDS_SETTINGS_APP_NOTIFICATIONS_LINK_TO_BROWSER_SETTINGS_DESCRIPTION" desc="In notifications OS Settings subpage, explanatory text for website notifications link."> - For browser notifications, go to <ph name="LINK_BEGIN"><a></ph>Chrome browser Settings<ph name="LINK_END"></a></ph> + For browser notifications, go to <ph name="LINK_BEGIN"><a href="#"></ph>Chrome browser Settings<ph name="LINK_END"></a></ph> </message> <message name="IDS_SETTINGS_APP_BADGING_TOGGLE_LABEL" desc="The label for the app badging toggle in the App Notifications page of OS Settings."> App badging
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7cd4b3f..071bb48 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5404,6 +5404,11 @@ kOmniboxSuggestionHeightVariations, "Uniform Omnibox Suggest Heights")}, + {"omnibox-grouping-framework", + flag_descriptions::kOmniboxGroupingFrameworkName, + flag_descriptions::kOmniboxGroupingFrameworkDescription, kOsAll, + FEATURE_VALUE_TYPE(omnibox::kGroupingFramework)}, + {"optimization-guide-debug-logs", flag_descriptions::kOptimizationGuideDebugLogsName, flag_descriptions::kOptimizationGuideDebugLogsDescription, kOsAll,
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index ebf7602..ba97112 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -4389,6 +4389,7 @@ "../ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc", "../ui/webui/settings/ash/search/search_handler_unittest.cc", "../ui/webui/settings/ash/search/search_tag_registry_unittest.cc", + "../ui/webui/settings/ash/search_engines_handler_unittest.cc", "../ui/webui/settings/ash/settings_user_action_tracker_unittest.cc", "../ui/webui/settings/chromeos/constants/routes_util_unittest.cc", "accessibility/pumpkin_installer_unittest.cc",
diff --git a/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.cc b/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.cc new file mode 100644 index 0000000..73ca0f1 --- /dev/null +++ b/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.cc
@@ -0,0 +1,61 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.h" + +#include "base/logging.h" +#include "base/metrics/histogram_functions.h" +#include "base/strings/strcat.h" + +namespace { + +constexpr char kHistogramNameBase[] = "Arc.AppSync.InitialSession."; +constexpr int kAppCountUmaExclusiveMax = 101; + +} // namespace + +namespace arc { + +ArcAppSyncMetricsHelper::ArcAppSyncMetricsHelper() = default; + +ArcAppSyncMetricsHelper::~ArcAppSyncMetricsHelper() = default; + +void ArcAppSyncMetricsHelper::SetTimeSyncStarted() { + time_sync_started_ = base::TimeTicks::Now(); + time_last_install_finished_ = time_sync_started_; +} + +void ArcAppSyncMetricsHelper::OnAppInstalled() { + time_last_install_finished_ = base::TimeTicks::Now(); + num_installed_apps_++; +} + +void ArcAppSyncMetricsHelper::SetAndRecordNumExpectedApps( + uint64_t num_expected_apps) { + num_expected_apps_ = num_expected_apps; + base::UmaHistogramExactLinear( + base::StrCat({kHistogramNameBase, "NumAppsExpected"}), num_expected_apps_, + kAppCountUmaExclusiveMax); +} + +void ArcAppSyncMetricsHelper::RecordMetrics() { + if (time_sync_started_ != time_last_install_finished_) { + const base::TimeDelta latency = + time_last_install_finished_ - time_sync_started_; + // Min is set to 30s since app installs typically take longer and an + // underflow bucket will be created + base::UmaHistogramCustomCounts( + base::StrCat({kHistogramNameBase, "Latency"}), latency.InSeconds(), + /*min=*/30, /*max=*/base::Hours(3).InSeconds(), /*buckets=*/50); + } + + base::UmaHistogramExactLinear( + base::StrCat({kHistogramNameBase, "NumAppsInstalled"}), + num_installed_apps_, kAppCountUmaExclusiveMax); + base::UmaHistogramExactLinear( + base::StrCat({kHistogramNameBase, "NumAppsNotInstalled"}), + num_expected_apps_ - num_installed_apps_, kAppCountUmaExclusiveMax); +} + +} // namespace arc
diff --git a/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.h b/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.h new file mode 100644 index 0000000..8dbb4c6 --- /dev/null +++ b/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.h
@@ -0,0 +1,42 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_APP_LIST_ARC_ARC_APP_SYNC_METRICS_HELPER_H_ +#define CHROME_BROWSER_ASH_APP_LIST_ARC_ARC_APP_SYNC_METRICS_HELPER_H_ + +#include "base/time/time.h" + +namespace arc { + +// Handles metrics for app sync. +class ArcAppSyncMetricsHelper { + public: + ArcAppSyncMetricsHelper(); + ~ArcAppSyncMetricsHelper(); + ArcAppSyncMetricsHelper(const ArcAppSyncMetricsHelper& other) = delete; + ArcAppSyncMetricsHelper& operator=(const ArcAppSyncMetricsHelper&) = delete; + + // Sets `time_sync_started_` to current time. + void SetTimeSyncStarted(); + + // When an app is installed, count of installed apps is incremented and + // the current time is recorded. + void OnAppInstalled(); + + // Sets `num_expected_apps_` and records the count in UMA. + void SetAndRecordNumExpectedApps(uint64_t num_expected_apps); + + // Records the remaining metrics in UMA. + void RecordMetrics(); + + private: + base::TimeTicks time_sync_started_; + base::TimeTicks time_last_install_finished_; + uint64_t num_installed_apps_ = 0; + uint64_t num_expected_apps_ = 0; +}; + +} // namespace arc + +#endif // CHROME_BROWSER_ASH_APP_LIST_ARC_ARC_APP_SYNC_METRICS_HELPER_H_
diff --git a/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper_unittest.cc b/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper_unittest.cc new file mode 100644 index 0000000..52fd1298 --- /dev/null +++ b/chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper_unittest.cc
@@ -0,0 +1,103 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.h" + +#include "base/test/metrics/histogram_tester.h" +#include "base/time/time.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +constexpr char kLatencyHistogramName[] = "Arc.AppSync.InitialSession.Latency"; +constexpr char kExpectedAppHistogramName[] = + "Arc.AppSync.InitialSession.NumAppsExpected"; +constexpr char kInstalledAppHistogramName[] = + "Arc.AppSync.InitialSession.NumAppsInstalled"; +constexpr char kNotInstalledAppHistogramName[] = + "Arc.AppSync.InitialSession.NumAppsNotInstalled"; + +} // namespace + +namespace arc { + +class ArcAppSyncMetricsHelperTest : public testing::Test { + public: + ArcAppSyncMetricsHelperTest(const ArcAppSyncMetricsHelperTest&) = delete; + ArcAppSyncMetricsHelperTest& operator=(const ArcAppSyncMetricsHelperTest&) = + delete; + + protected: + ArcAppSyncMetricsHelperTest() = default; + + base::test::TaskEnvironment task_environment{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + ArcAppSyncMetricsHelper metrics_helper_; + base::HistogramTester tester; +}; + +TEST_F(ArcAppSyncMetricsHelperTest, + OneAppExpectedAndNotDownloaded_ThenDontRecordLatency) { + metrics_helper_.SetTimeSyncStarted(); + metrics_helper_.SetAndRecordNumExpectedApps(1); + metrics_helper_.RecordMetrics(); + + tester.ExpectUniqueSample(kNotInstalledAppHistogramName, 1, 1); + tester.ExpectUniqueSample(kInstalledAppHistogramName, 0, 1); + tester.ExpectUniqueSample(kExpectedAppHistogramName, 1, 1); + tester.ExpectTotalCount(kLatencyHistogramName, 0); +} + +TEST_F(ArcAppSyncMetricsHelperTest, OneAppExpectedAndDownloaded) { + base::TimeDelta expected_latency = base::Minutes(1); + metrics_helper_.SetTimeSyncStarted(); + metrics_helper_.SetAndRecordNumExpectedApps(1); + task_environment.AdvanceClock(expected_latency); + metrics_helper_.OnAppInstalled(); + metrics_helper_.RecordMetrics(); + + tester.ExpectUniqueSample(kNotInstalledAppHistogramName, 0, 1); + tester.ExpectUniqueSample(kInstalledAppHistogramName, 1, 1); + tester.ExpectUniqueSample(kExpectedAppHistogramName, 1, 1); + tester.ExpectUniqueSample(kLatencyHistogramName, expected_latency.InSeconds(), + 1); +} + +TEST_F(ArcAppSyncMetricsHelperTest, TwoAppsExpectedAndOneDownloaded) { + base::TimeDelta expected_latency = base::Minutes(5); + metrics_helper_.SetTimeSyncStarted(); + metrics_helper_.SetAndRecordNumExpectedApps(2); + task_environment.AdvanceClock(expected_latency); + metrics_helper_.OnAppInstalled(); + metrics_helper_.RecordMetrics(); + + tester.ExpectUniqueSample(kNotInstalledAppHistogramName, 1, 1); + tester.ExpectUniqueSample(kInstalledAppHistogramName, 1, 1); + tester.ExpectUniqueSample(kExpectedAppHistogramName, 2, 1); + tester.ExpectUniqueSample(kLatencyHistogramName, expected_latency.InSeconds(), + 1); +} + +TEST_F(ArcAppSyncMetricsHelperTest, + ThreeAppsExpectedAndDownloaded_ThenRecordTotalLatency) { + int32_t num_expected_apps = 3; + base::TimeDelta latency_per_app = base::Minutes(1); + metrics_helper_.SetTimeSyncStarted(); + metrics_helper_.SetAndRecordNumExpectedApps(num_expected_apps); + for (int i = 0; i < num_expected_apps; i++) { + task_environment.AdvanceClock(latency_per_app); + metrics_helper_.OnAppInstalled(); + } + metrics_helper_.RecordMetrics(); + base::TimeDelta expected_latency = latency_per_app * num_expected_apps; + + tester.ExpectUniqueSample(kNotInstalledAppHistogramName, 0, 1); + tester.ExpectUniqueSample(kInstalledAppHistogramName, 3, 1); + tester.ExpectUniqueSample(kExpectedAppHistogramName, 3, 1); + tester.ExpectUniqueSample(kLatencyHistogramName, expected_latency.InSeconds(), + 1); +} + +} // namespace arc
diff --git a/chrome/browser/ash/app_list/arc/arc_package_syncable_service.cc b/chrome/browser/ash/app_list/arc/arc_package_syncable_service.cc index 108c6cf4..bbf8168 100644 --- a/chrome/browser/ash/app_list/arc/arc_package_syncable_service.cc +++ b/chrome/browser/ash/app_list/arc/arc_package_syncable_service.cc
@@ -10,9 +10,11 @@ #include "ash/components/arc/arc_util.h" #include "ash/components/arc/session/connection_holder.h" +#include "ash/constants/ash_pref_names.h" #include "base/containers/contains.h" #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ash/app_list/arc/arc_package_syncable_service_factory.h" +#include "chrome/browser/ash/arc/session/arc_session_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "components/prefs/scoped_user_pref_update.h" @@ -95,11 +97,20 @@ prefs_(prefs) { if (prefs_) prefs_->AddObserver(this); + + auto* arc_session_manager = arc::ArcSessionManager::Get(); + DCHECK(arc_session_manager); + arc_session_manager->AddObserver(this); } ArcPackageSyncableService::~ArcPackageSyncableService() { if (prefs_) prefs_->RemoveObserver(this); + + // arc::ArcSessionManager may be released first. + if (auto* arc_session_manager = ArcSessionManager::Get()) { + arc_session_manager->RemoveObserver(this); + } } // static @@ -149,6 +160,8 @@ sync_processor_ = std::move(sync_processor); sync_error_handler_ = std::move(error_handler); + metrics_helper_.SetTimeSyncStarted(); + uint64_t num_expected_apps = 0; const std::vector<std::string> local_packages = prefs_->GetPackagesFromPrefs(); @@ -167,11 +180,15 @@ if (!base::Contains(local_package_set, package_name)) { pending_install_items_[package_name] = std::move(sync_item); InstallPackage(pending_install_items_[package_name].get()); + num_expected_apps++; } else { // TODO(lgcheng@) may need to handle update exsiting package here. sync_items_[package_name] = std::move(sync_item); } } + if (profile_->GetPrefs()->GetBoolean(ash::prefs::kRecordArcAppSyncMetrics)) { + metrics_helper_.SetAndRecordNumExpectedApps(num_expected_apps); + } // Creates sync items for local unsynced packages. syncer::SyncChangeList change_list; @@ -308,6 +325,7 @@ sync_items_[package_name] = std::move(install_iter->second); pending_install_items_.erase(install_iter); + metrics_helper_.OnAppInstalled(); return; } @@ -478,4 +496,11 @@ return true; } +void ArcPackageSyncableService::OnArcSessionStopped(ArcStopReason stop_reason) { + if (profile_->GetPrefs()->GetBoolean(ash::prefs::kRecordArcAppSyncMetrics)) { + metrics_helper_.RecordMetrics(); + } + profile_->GetPrefs()->ClearPref(ash::prefs::kRecordArcAppSyncMetrics); +} + } // namespace arc
diff --git a/chrome/browser/ash/app_list/arc/arc_package_syncable_service.h b/chrome/browser/ash/app_list/arc/arc_package_syncable_service.h index 1a6f255..25bc617 100644 --- a/chrome/browser/ash/app_list/arc/arc_package_syncable_service.h +++ b/chrome/browser/ash/app_list/arc/arc_package_syncable_service.h
@@ -12,6 +12,8 @@ #include <unordered_map> #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ash/app_list/arc/arc_app_sync_metrics_helper.h" +#include "chrome/browser/ash/arc/session/arc_session_manager_observer.h" #include "chrome/browser/sync/glue/sync_start_util.h" #include "components/keyed_service/core/keyed_service.h" #include "components/sync/model/sync_change.h" @@ -28,10 +30,11 @@ namespace arc { -// Class that syncs ARC pakcages install/uninstall. +// Class that syncs ARC packages install/uninstall. class ArcPackageSyncableService : public syncer::SyncableService, public KeyedService, - public ArcAppListPrefs::Observer { + public ArcAppListPrefs::Observer, + public ArcSessionManagerObserver { public: struct SyncItem { SyncItem(const std::string& package_name, @@ -84,6 +87,9 @@ bool uninstalled) override; void OnPackageListInitialRefreshed() override; + // ArcSessionManagerObserver: + void OnArcSessionStopped(ArcStopReason stop_reason) override; + // Sends adds/updates sync change to sync server. void SendSyncChange( const mojom::ArcPackageInfo& package_info, @@ -135,6 +141,8 @@ syncer::SyncableService::StartSyncFlare flare_; ArcAppListPrefs* const prefs_; + + ArcAppSyncMetricsHelper metrics_helper_; }; } // namespace arc
diff --git a/chrome/browser/ash/arc/policy/arc_policy_util_unittest.cc b/chrome/browser/ash/arc/policy/arc_policy_util_unittest.cc index ad77c25d..4ebabca9 100644 --- a/chrome/browser/ash/arc/policy/arc_policy_util_unittest.cc +++ b/chrome/browser/ash/arc/policy/arc_policy_util_unittest.cc
@@ -32,18 +32,6 @@ {"testPackage3", "BLOCKED"}, {"testPackage4", "AVAILABLE"}, {"testPackage5", "AVAILABLE"}, {"testPackage6", "REQUIRED"}}; -} // namespace - -class ArcPolicyUtilTest : public testing::Test { - public: - ArcPolicyUtilTest(const ArcPolicyUtilTest&) = delete; - ArcPolicyUtilTest& operator=(const ArcPolicyUtilTest&) = delete; - - protected: - ArcPolicyUtilTest() = default; - base::HistogramTester tester; -}; - std::string CreatePolicyWithAppInstalls( std::map<std::string, std::string> package_map) { base::Value::Dict arc_policy; @@ -62,6 +50,19 @@ return arc_policy_string; } +} // namespace + +class ArcPolicyUtilTest : public testing::Test { + public: + ArcPolicyUtilTest(const ArcPolicyUtilTest&) = delete; + ArcPolicyUtilTest& operator=(const ArcPolicyUtilTest&) = delete; + + protected: + ArcPolicyUtilTest() = default; + + base::HistogramTester tester_; +}; + TEST_F(ArcPolicyUtilTest, GetRequestedPackagesFromArcPolicy) { std::set<std::string> expected = {"testPackage", "testPackage6"}; std::string policy = CreatePolicyWithAppInstalls(kTestMap); @@ -71,7 +72,7 @@ EXPECT_EQ(result, expected); } -TEST_F(ArcPolicyUtilTest, RecordInstallTypesInPolicy_OneOfEachType) { +TEST_F(ArcPolicyUtilTest, RecordInstallTypesInPolicyWithOneOfEachType) { std::map<std::string, std::string> test_map = { {"testPackage", "OPTIONAL"}, {"testPackage2", "REQUIRED"}, @@ -86,49 +87,46 @@ std::string policy = CreatePolicyWithAppInstalls(test_map); arc::policy_util::RecordInstallTypesInPolicy(policy); - tester.ExpectBucketCount(kInstallTypeHistogram, kUnknownBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kOptionalBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kRequiredBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kPreloadBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kAvailableBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kRequiredForSetupBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kKioskBucket, 1); - tester.ExpectTotalCount(kInstallTypeHistogram, 9); + tester_.ExpectBucketCount(kInstallTypeHistogram, kUnknownBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kOptionalBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kRequiredBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kPreloadBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kAvailableBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kRequiredForSetupBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kKioskBucket, 1); + tester_.ExpectTotalCount(kInstallTypeHistogram, 9); } -TEST_F(ArcPolicyUtilTest, RecordInstallTypesInPolicy_ComplexPolicy) { +TEST_F(ArcPolicyUtilTest, RecordInstallTypesInPolicyWithComplexPolicy) { std::string policy = CreatePolicyWithAppInstalls(kTestMap); arc::policy_util::RecordInstallTypesInPolicy(policy); - tester.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kAvailableBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kRequiredBucket, 1); - tester.ExpectTotalCount(kInstallTypeHistogram, 4); + tester_.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kAvailableBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kRequiredBucket, 1); + tester_.ExpectTotalCount(kInstallTypeHistogram, 4); } -TEST_F(ArcPolicyUtilTest, RecordInstallTypesInPolicy_PolicyUpdate) { - std::string policy = CreatePolicyWithAppInstalls(kTestMap); +TEST_F(ArcPolicyUtilTest, RecordInstallTypesInPolicyAfterPolicyUpdate) { + std::map<std::string, std::string> test_map = { + {"testPackage", "FORCE_INSTALLED"}}; + std::string policy = CreatePolicyWithAppInstalls(test_map); arc::policy_util::RecordInstallTypesInPolicy(policy); - tester.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kAvailableBucket, 1); - tester.ExpectBucketCount(kInstallTypeHistogram, kRequiredBucket, 1); - tester.ExpectTotalCount(kInstallTypeHistogram, 4); + tester_.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 1); + tester_.ExpectTotalCount(kInstallTypeHistogram, 1); - kTestMap["anotherTestPackage"] = "BLOCKED"; - kTestMap["anotherTestPackage2"] = "KIOSK"; - policy = CreatePolicyWithAppInstalls(kTestMap); + test_map["anotherTestPackage"] = "BLOCKED"; + test_map["anotherTestPackage2"] = "KIOSK"; + policy = CreatePolicyWithAppInstalls(test_map); arc::policy_util::RecordInstallTypesInPolicy(policy); - tester.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 2); - tester.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 2); - tester.ExpectBucketCount(kInstallTypeHistogram, kAvailableBucket, 2); - tester.ExpectBucketCount(kInstallTypeHistogram, kRequiredBucket, 2); - tester.ExpectBucketCount(kInstallTypeHistogram, kKioskBucket, 1); - tester.ExpectTotalCount(kInstallTypeHistogram, 9); + tester_.ExpectBucketCount(kInstallTypeHistogram, kForceInstalledBucket, 2); + tester_.ExpectBucketCount(kInstallTypeHistogram, kBlockedBucket, 1); + tester_.ExpectBucketCount(kInstallTypeHistogram, kKioskBucket, 1); + tester_.ExpectTotalCount(kInstallTypeHistogram, 4); } } // namespace arc::policy_util
diff --git a/chrome/browser/ash/crosapi/persistent_forced_extension_keep_alive_unittest.cc b/chrome/browser/ash/crosapi/persistent_forced_extension_keep_alive_unittest.cc index b006502..277f93a 100644 --- a/chrome/browser/ash/crosapi/persistent_forced_extension_keep_alive_unittest.cc +++ b/chrome/browser/ash/crosapi/persistent_forced_extension_keep_alive_unittest.cc
@@ -62,12 +62,12 @@ } void SetInstallForceList(const std::string& extension_id) { - std::unique_ptr<base::Value> dict = + base::Value::Dict dict = extensions::DictionaryBuilder() .Set(extension_id, extensions::DictionaryBuilder().Build()) .Build(); profile_->GetPrefs()->Set(extensions::pref_names::kInstallForceList, - std::move(*dict)); + base::Value(std::move(dict))); } FakeBrowserManager& browser_manager() { return *browser_manager_; }
diff --git a/chrome/browser/ash/dbus/org.chromium.ChromeFeaturesService.conf b/chrome/browser/ash/dbus/org.chromium.ChromeFeaturesService.conf index 86ad8fe..180c30ff 100644 --- a/chrome/browser/ash/dbus/org.chromium.ChromeFeaturesService.conf +++ b/chrome/browser/ash/dbus/org.chromium.ChromeFeaturesService.conf
@@ -54,4 +54,11 @@ send_interface="org.chromium.ChromeFeaturesServiceInterface" send_member="IsFeatureEnabled"/> </policy> + + <!-- limit dlp visibility to only IsFeatureEnabled --> + <policy user="dlp"> + <allow send_destination="org.chromium.ChromeFeaturesService" + send_interface="org.chromium.ChromeFeaturesServiceInterface" + send_member="IsFeatureEnabled"/> + </policy> </busconfig>
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc index c5b5a67..7535bda 100644 --- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
@@ -589,6 +589,8 @@ DCHECK(value.is_bool()); } else if (pref_name == quick_answers::prefs::kQuickAnswersConsentStatus) { DCHECK(value.is_int()); + } else if (pref_name == arc::prefs::kArcShowResizeLockSplashScreenLimits) { + DCHECK(value.is_int()); } else { return "The pref " + pref_name + " is not allowed."; }
diff --git a/chrome/browser/ash/login/screens/multidevice_setup_screen.cc b/chrome/browser/ash/login/screens/multidevice_setup_screen.cc index 032f982..9a7efae5 100644 --- a/chrome/browser/ash/login/screens/multidevice_setup_screen.cc +++ b/chrome/browser/ash/login/screens/multidevice_setup_screen.cc
@@ -8,12 +8,15 @@ #include "base/logging.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_macros.h" +#include "chrome/browser/ash/device_sync/device_sync_client_factory.h" #include "chrome/browser/ash/login/users/chrome_user_manager_util.h" #include "chrome/browser/ash/login/wizard_context.h" #include "chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h" #include "chrome/browser/ash/multidevice_setup/oobe_completion_tracker_factory.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/webui/ash/login/multidevice_setup_screen_handler.h" +#include "chromeos/ash/components/multidevice/logging/logging.h" +#include "chromeos/ash/services/device_sync/public/cpp/device_sync_client.h" #include "chromeos/ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "chromeos/ash/services/multidevice_setup/public/cpp/oobe_completion_tracker.h" @@ -50,7 +53,13 @@ DCHECK(view_); } -MultiDeviceSetupScreen::~MultiDeviceSetupScreen() = default; +MultiDeviceSetupScreen::~MultiDeviceSetupScreen() { + if (skipped_ && !skipped_reason_determined_) { + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason:: + kDestroyedBeforeReasonCouldBeDetermined); + } +} void MultiDeviceSetupScreen::TryInitSetupClient() { if (!setup_client_) { @@ -65,25 +74,39 @@ if (context.skip_post_login_screens_for_tests || chrome_user_manager_util::IsPublicSessionOrEphemeralLogin()) { exit_callback_.Run(Result::NOT_APPLICABLE); + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kPublicSessionOrEphemeralLogin); + skipped_ = true; return true; } TryInitSetupClient(); - // If there is no eligible multi-device host phone or if there is a phone and - // it has already been set, skip the setup flow. + + // Skip if the setup client wasn't successfully initialized. if (!setup_client_) { + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kSetupClientNotInitialized); exit_callback_.Run(Result::NOT_APPLICABLE); - return true; - } - if (setup_client_->GetHostStatus().first != - multidevice_setup::mojom::HostStatus::kEligibleHostExistsButNoHostSet) { - VLOG(1) << "Skipping MultiDevice setup screen; host status: " - << setup_client_->GetHostStatus().first; - exit_callback_.Run(Result::NOT_APPLICABLE); + skipped_ = true; return true; } - return false; + // Do not skip if potential host exists but none is set yet. + if (setup_client_->GetHostStatus().first == + multidevice_setup::mojom::HostStatus::kEligibleHostExistsButNoHostSet) { + skipped_ = false; + return false; + } + + skipped_ = true; + VLOG(1) << "Skipping MultiDevice setup screen; host status: " + << setup_client_->GetHostStatus().first; + exit_callback_.Run(Result::NOT_APPLICABLE); + + // Determine underlying reason why the screen is being skipped. + GetBetterTogetherMetadataStatus(); + + return true; } void MultiDeviceSetupScreen::ShowImpl() { @@ -119,6 +142,123 @@ } } +void MultiDeviceSetupScreen::GetBetterTogetherMetadataStatus() { + if (!device_sync_client_) { + device_sync_client_ = device_sync::DeviceSyncClientFactory::GetForProfile( + ProfileManager::GetActiveUserProfile()); + } + + device_sync_client_->GetBetterTogetherMetadataStatus( + base::BindOnce(&MultiDeviceSetupScreen::OnGetBetterTogetherMetadataStatus, + weak_factory_.GetWeakPtr())); +} + +void MultiDeviceSetupScreen::OnGetBetterTogetherMetadataStatus( + device_sync::BetterTogetherMetadataStatus status) { + PA_LOG(INFO) << "Skipped MultiDevice setup screen; " + "better_together_metadata_status: " + << status; + switch (status) { + case device_sync::BetterTogetherMetadataStatus::kMetadataDecrypted: + // If the better together metadata status is in its expected final state, + // then we know that device sync successfully finished. Investigate the + // host status for more granular information. + setup_client_->GetHostStatus().first == + multidevice_setup::mojom::HostStatus::kNoEligibleHosts + ? RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason:: + kDeviceSyncFinishedAndNoEligibleHostPhone) + : RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kHostPhoneAlreadySet); + return; + case device_sync::BetterTogetherMetadataStatus:: + kWaitingToProcessDeviceMetadata: + [[fallthrough]]; + case device_sync::BetterTogetherMetadataStatus::kGroupPrivateKeyMissing: + // If the better together metadata status is + // kWaitingToProcessDeviceMetadata or kGroupPrivateKeyMissing, we must + // inspect the group private key status to get a more granular + // understanding. + GetGroupPrivateKeyStatus(); + return; + case device_sync::BetterTogetherMetadataStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason:: + kDeviceSyncNotInitializedDuringBetterTogetherMetadataStatusFetch); + return; + case device_sync::BetterTogetherMetadataStatus::kEncryptedMetadataEmpty: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kEncryptedMetadataEmpty); + return; + } +} + +void MultiDeviceSetupScreen::GetGroupPrivateKeyStatus() { + if (!device_sync_client_) { + device_sync_client_ = device_sync::DeviceSyncClientFactory::GetForProfile( + ProfileManager::GetActiveUserProfile()); + } + + device_sync_client_->GetGroupPrivateKeyStatus( + base::BindOnce(&MultiDeviceSetupScreen::OnGetGroupPrivateKeyStatus, + weak_factory_.GetWeakPtr())); +} + +void MultiDeviceSetupScreen::OnGetGroupPrivateKeyStatus( + device_sync::GroupPrivateKeyStatus status) { + PA_LOG(INFO) << "Skipped MultiDevice setup screen; group private key status: " + << status; + + switch (status) { + case device_sync::GroupPrivateKeyStatus::kWaitingForGroupPrivateKey: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kWaitingForGroupPrivateKey); + return; + case device_sync::GroupPrivateKeyStatus:: + kNoEncryptedGroupPrivateKeyReceived: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason:: + kNoEncryptedGroupPrivateKeyReceived); + return; + case device_sync::GroupPrivateKeyStatus::kEncryptedGroupPrivateKeyEmpty: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kEncryptedGroupPrivateKeyEmpty); + return; + case device_sync::GroupPrivateKeyStatus:: + kLocalDeviceSyncBetterTogetherKeyMissing: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason:: + kLocalDeviceSyncBetterTogetherKeyMissing); + return; + case device_sync::GroupPrivateKeyStatus::kGroupPrivateKeyDecryptionFailed: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kGroupPrivateKeyDecryptionFailed); + return; + case device_sync::GroupPrivateKeyStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized: + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason:: + kDeviceSyncNotInitializedDuringGroupPrivateKeyStatusFetch); + return; + case device_sync::GroupPrivateKeyStatus:: + kGroupPrivateKeySuccessfullyDecrypted: + // This is the expected finished status of the GroupPrivateKey. If this + // point is reached, there's no known reason why the setup client wouldn't + // be initialized. + RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason::kUnknown); + return; + } +} + +void MultiDeviceSetupScreen::RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason reason) { + skipped_reason_determined_ = true; + UMA_HISTOGRAM_ENUMERATION( + "OOBE.StepShownStatus.Multidevice-setup-screen.Skipped", reason); +} + void MultiDeviceSetupScreen::RecordMultiDeviceSetupOOBEUserChoiceHistogram( MultiDeviceSetupOOBEUserChoice value) { UMA_HISTOGRAM_ENUMERATION("MultiDeviceSetup.OOBE.UserChoice", value);
diff --git a/chrome/browser/ash/login/screens/multidevice_setup_screen.h b/chrome/browser/ash/login/screens/multidevice_setup_screen.h index e856903c..62875ecb 100644 --- a/chrome/browser/ash/login/screens/multidevice_setup_screen.h +++ b/chrome/browser/ash/login/screens/multidevice_setup_screen.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ash/login/screens/base_screen.h" +#include "chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h" namespace ash { @@ -20,6 +21,10 @@ class MultiDeviceSetupClient; } +namespace device_sync { +class DeviceSyncClient; +} + class MultiDeviceSetupScreen : public BaseScreen { public: enum class Result { NEXT, NOT_APPLICABLE }; @@ -50,6 +55,11 @@ setup_client_ = client; } + void set_device_sync_client_for_testing( + device_sync::DeviceSyncClient* client) { + device_sync_client_ = client; + } + protected: // BaseScreen: bool MaybeSkip(WizardContext& context) override; @@ -70,16 +80,54 @@ kMaxValue = kDeclined }; + // This enum is tied directly to the OobeMultideviceScreenSkippedReason UMA + // enum defined in //tools/metrics/histograms/enums.xml, and should always + // reflect it (do not change one without changing the other). Entries should + // be never modified or deleted. Only additions possible. + enum class OobeMultideviceScreenSkippedReason { + kPublicSessionOrEphemeralLogin = 0, + kHostPhoneAlreadySet = 1, + kDeviceSyncFinishedAndNoEligibleHostPhone = 2, + kSetupClientNotInitialized = 3, + kDeviceSyncNotInitializedDuringBetterTogetherMetadataStatusFetch = 4, + kDeviceSyncNotInitializedDuringGroupPrivateKeyStatusFetch = 5, + kEncryptedMetadataEmpty = 6, + kWaitingForGroupPrivateKey = 7, + kNoEncryptedGroupPrivateKeyReceived = 8, + kEncryptedGroupPrivateKeyEmpty = 9, + kLocalDeviceSyncBetterTogetherKeyMissing = 10, + kGroupPrivateKeyDecryptionFailed = 11, + kDestroyedBeforeReasonCouldBeDetermined = 12, + kUnknown = 13, + kMaxValue = kUnknown + }; + // Inits `setup_client_` if it was not initialized before. void TryInitSetupClient(); + void GetBetterTogetherMetadataStatus(); + + void OnGetBetterTogetherMetadataStatus( + device_sync::BetterTogetherMetadataStatus status); + + void GetGroupPrivateKeyStatus(); + + void OnGetGroupPrivateKeyStatus(device_sync::GroupPrivateKeyStatus status); + + void RecordOobeMultideviceScreenSkippedReasonHistogram( + OobeMultideviceScreenSkippedReason reason); + static void RecordMultiDeviceSetupOOBEUserChoiceHistogram( MultiDeviceSetupOOBEUserChoice value); multidevice_setup::MultiDeviceSetupClient* setup_client_ = nullptr; + device_sync::DeviceSyncClient* device_sync_client_ = nullptr; + bool skipped_ = false; + bool skipped_reason_determined_ = false; base::WeakPtr<MultiDeviceSetupScreenView> view_; ScreenExitCallback exit_callback_; + base::WeakPtrFactory<MultiDeviceSetupScreen> weak_factory_{this}; }; } // namespace ash
diff --git a/chrome/browser/ash/login/screens/multidevice_setup_screen_browsertest.cc b/chrome/browser/ash/login/screens/multidevice_setup_screen_browsertest.cc index b73e680..6318ef45 100644 --- a/chrome/browser/ash/login/screens/multidevice_setup_screen_browsertest.cc +++ b/chrome/browser/ash/login/screens/multidevice_setup_screen_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/webui/ash/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/multidevice_setup_screen_handler.h" +#include "chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.h" #include "chromeos/ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h" #include "content/public/test/browser_test.h" @@ -41,6 +42,9 @@ std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>(); screen->set_multidevice_setup_client_for_testing( fake_multidevice_setup_client_.get()); + fake_device_sync_client_ = + std::make_unique<device_sync::FakeDeviceSyncClient>(); + screen->set_device_sync_client_for_testing(fake_device_sync_client_.get()); OobeBaseTest::SetUpOnMainThread(); } @@ -102,10 +106,202 @@ !Accepted); } + void CheckSkipped(bool should_be_skipped) { + if (should_be_skipped) { + EXPECT_EQ(screen_result_.value(), + MultiDeviceSetupScreen::Result::NOT_APPLICABLE); + histogram_tester_.ExpectBucketCount( + "OOBE.StepShownStatus.Multidevice-setup-screen", true, 0); + histogram_tester_.ExpectBucketCount( + "OOBE.StepShownStatus.Multidevice-setup-screen", false, 1); + return; + } + + histogram_tester_.ExpectBucketCount( + "OOBE.StepShownStatus.Multidevice-setup-screen", true, 1); + histogram_tester_.ExpectBucketCount( + "OOBE.StepShownStatus.Multidevice-setup-screen", false, 0); + } + + void CheckHostPhoneAlreadySetSkippedReason() { + multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice + host_status_with_device = multidevice_setup::MultiDeviceSetupClient:: + GenerateDefaultHostStatusWithDevice(); + host_status_with_device.first = + multidevice_setup::mojom::HostStatus::kHostSetButNotYetVerified; + fake_multidevice_setup_client_->SetHostStatusWithDevice( + host_status_with_device); + + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kMetadataDecrypted, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kGroupPrivateKeySuccessfullyDecrypted, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kHostPhoneAlreadySet); + } + + void CheckDeviceSyncFinishedAndNoEligibleHostPhoneSkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kMetadataDecrypted, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kGroupPrivateKeySuccessfullyDecrypted, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kDeviceSyncFinishedAndNoEligibleHostPhone); + } + + void + CheckDeviceSyncNotInitializedDuringBetterTogetherMetadataStatusFetchSkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kDeviceSyncNotInitializedDuringBetterTogetherMetadataStatusFetch); + } + + void + CheckDeviceSyncNotInitializedDuringGroupPrivateKeyStatusFetchSkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kWaitingToProcessDeviceMetadata, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kDeviceSyncNotInitializedDuringGroupPrivateKeyStatusFetch); + } + + void CheckEncryptedMetadataEmptySkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kEncryptedMetadataEmpty, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kGroupPrivateKeySuccessfullyDecrypted, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kEncryptedMetadataEmpty); + } + + void CheckWaitingForGroupPrivateKeySkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kGroupPrivateKeyMissing, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus::kWaitingForGroupPrivateKey, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kWaitingForGroupPrivateKey); + } + + void CheckNoEncryptedGroupPrivateKeyReceivedSkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kGroupPrivateKeyMissing, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus::kNoEncryptedGroupPrivateKeyReceived, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kNoEncryptedGroupPrivateKeyReceived); + } + + void CheckEncryptedGroupPrivateKeyEmptySkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kGroupPrivateKeyMissing, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus::kEncryptedGroupPrivateKeyEmpty, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kEncryptedGroupPrivateKeyEmpty); + } + + void CheckLocalDeviceSyncBetterTogetherKeyMissingSkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kGroupPrivateKeyMissing, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kLocalDeviceSyncBetterTogetherKeyMissing, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kLocalDeviceSyncBetterTogetherKeyMissing); + } + + void CheckGroupPrivateKeyDecryptionFailedSkippedReason() { + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kGroupPrivateKeyMissing, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus::kGroupPrivateKeyDecryptionFailed, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason:: + kGroupPrivateKeyDecryptionFailed); + } + + void CheckUnknownSkippedReason() { + // This combination of better together metadata status and group private key + // status should never actually occur together + CheckSkippedReason( + /*better_together_metadata_status=*/device_sync:: + BetterTogetherMetadataStatus::kGroupPrivateKeyMissing, + /*group_private_key_status=*/ + device_sync::GroupPrivateKeyStatus:: + kGroupPrivateKeySuccessfullyDecrypted, + /*expected_skipped_reason=*/ + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason::kUnknown); + } + absl::optional<MultiDeviceSetupScreen::Result> screen_result_; base::HistogramTester histogram_tester_; private: + void CheckSkippedReason( + device_sync::BetterTogetherMetadataStatus better_together_metadata_status, + device_sync::GroupPrivateKeyStatus group_private_key_status, + MultiDeviceSetupScreen::OobeMultideviceScreenSkippedReason + expected_skipped_reason) { + CheckSkipped(/*should_be_skipped=*/true); + EXPECT_TRUE(fake_device_sync_client_ + ->GetBetterTogetherMetadataStatusCallbackQueueSize() > 0); + fake_device_sync_client_ + ->InvokePendingGetBetterTogetherMetadataStatusCallback( + better_together_metadata_status); + + // The screen should only attempt to fetch the group private key status when + // the better together metadata status is kWaitingToProcessDeviceMetadata or + // kGroupPrivateKeyMissing + if (better_together_metadata_status == + device_sync::BetterTogetherMetadataStatus:: + kWaitingToProcessDeviceMetadata || + better_together_metadata_status == + device_sync::BetterTogetherMetadataStatus:: + kGroupPrivateKeyMissing) { + EXPECT_TRUE(fake_device_sync_client_ + ->GetGroupPrivateKeyStatusCallbackQueueSize() > 0); + fake_device_sync_client_->InvokePendingGetGroupPrivateKeyStatusCallback( + group_private_key_status); + } else { + EXPECT_FALSE(fake_device_sync_client_ + ->GetGroupPrivateKeyStatusCallbackQueueSize() > 0); + } + + histogram_tester_.ExpectBucketCount( + "OOBE.StepShownStatus.Multidevice-setup-screen.Skipped", + expected_skipped_reason, 1); + } + void HandleScreenExit(MultiDeviceSetupScreen::Result result) { ASSERT_FALSE(screen_exited_); screen_exited_ = true; @@ -118,6 +314,7 @@ base::RepeatingClosure screen_exit_callback_; std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient> fake_multidevice_setup_client_; + std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; LoginManagerMixin login_manager_mixin_{&mixin_host_}; }; @@ -135,6 +332,7 @@ "OOBE.StepCompletionTimeByExitReason.Multidevice-setup-screen.Next", 1); histogram_tester_.ExpectTotalCount( "OOBE.StepCompletionTime.Multidevice-setup-screen", 1); + CheckSkipped(/*should_be_skipped=*/false); CheckUserChoice(true); } @@ -151,19 +349,86 @@ "OOBE.StepCompletionTimeByExitReason.Multidevice-setup-screen.Next", 1); histogram_tester_.ExpectTotalCount( "OOBE.StepCompletionTime.Multidevice-setup-screen", 1); + CheckSkipped(/*should_be_skipped=*/false); CheckUserChoice(false); } -IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, Skipped) { +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_HostPhoneAlreadySet) { ShowMultiDeviceSetupScreen(); - WaitForScreenExit(); - EXPECT_EQ(screen_result_.value(), - MultiDeviceSetupScreen::Result::NOT_APPLICABLE); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTimeByExitReason.Multidevice-setup-screen.Next", 0); - histogram_tester_.ExpectTotalCount( - "OOBE.StepCompletionTime.Multidevice-setup-screen", 0); + CheckHostPhoneAlreadySetSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_DeviceSyncFinishedAndNoEligibleHostPhone) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckDeviceSyncFinishedAndNoEligibleHostPhoneSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F( + MultiDeviceSetupScreenTest, + SkippedReason_DeviceSyncNotInitializedDuringBetterTogetherMetadataStatusFetch) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckDeviceSyncNotInitializedDuringBetterTogetherMetadataStatusFetchSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F( + MultiDeviceSetupScreenTest, + SkippedReason_DeviceSyncNotInitializedDuringGroupPrivateKeyStatusFetch) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckDeviceSyncNotInitializedDuringGroupPrivateKeyStatusFetchSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_EncryptedMetadataEmpty) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckEncryptedMetadataEmptySkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_WaitingForGroupPrivateKey) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckWaitingForGroupPrivateKeySkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_NoEncryptedGroupPrivateKeyReceived) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckNoEncryptedGroupPrivateKeyReceivedSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_EncryptedGroupPrivateKeyEmpty) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckEncryptedGroupPrivateKeyEmptySkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_LocalDeviceSyncBetterTogetherKeyMissing) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckLocalDeviceSyncBetterTogetherKeyMissingSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, + SkippedReason_GroupPrivateKeyDecryptionFailed) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckGroupPrivateKeyDecryptionFailedSkippedReason(); +} + +IN_PROC_BROWSER_TEST_F(MultiDeviceSetupScreenTest, SkippedReason_Unknown) { + ShowMultiDeviceSetupScreen(); + WaitForScreenExit(); + CheckUnknownSkippedReason(); } } // namespace ash
diff --git a/chrome/browser/ash/login/screens/sync_consent_screen.cc b/chrome/browser/ash/login/screens/sync_consent_screen.cc index 10174cc..f98e60e 100644 --- a/chrome/browser/ash/login/screens/sync_consent_screen.cc +++ b/chrome/browser/ash/login/screens/sync_consent_screen.cc
@@ -166,6 +166,7 @@ void SyncConsentScreen::Finish(Result result) { DCHECK(profile_); + profile_->GetPrefs()->SetBoolean(prefs::kRecordArcAppSyncMetrics, true); // Always set completed, even if the dialog was skipped (e.g. by policy). profile_->GetPrefs()->SetBoolean(prefs::kSyncOobeCompleted, true); // Record whether the dialog was shown, skipped, etc.
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc b/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc index 9cc90a89..154c9a93 100644 --- a/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc +++ b/chrome/browser/ash/login/users/avatar/user_image_manager_browsertest.cc
@@ -602,7 +602,7 @@ ADD_FAILURE(); } std::string policy; - base::JSONWriter::Write(*policy::test::ConstructExternalDataReference( + base::JSONWriter::Write(policy::test::ConstructExternalDataReference( embedded_test_server() ->GetURL(std::string("/") + relative_path) .spec(),
diff --git a/chrome/browser/ash/login/users/wallpaper_policy_browsertest.cc b/chrome/browser/ash/login/users/wallpaper_policy_browsertest.cc index dff1ad3..f9f6eff 100644 --- a/chrome/browser/ash/login/users/wallpaper_policy_browsertest.cc +++ b/chrome/browser/ash/login/users/wallpaper_policy_browsertest.cc
@@ -241,7 +241,7 @@ ADD_FAILURE(); } std::string policy; - base::JSONWriter::Write(*policy::test::ConstructExternalDataReference( + base::JSONWriter::Write(policy::test::ConstructExternalDataReference( embedded_test_server() ->GetURL(std::string("/") + relative_path) .spec(),
diff --git a/chrome/browser/ash/mobile/mobile_activator.cc b/chrome/browser/ash/mobile/mobile_activator.cc index 9f104c18..b120b09 100644 --- a/chrome/browser/ash/mobile/mobile_activator.cc +++ b/chrome/browser/ash/mobile/mobile_activator.cc
@@ -180,9 +180,8 @@ StartActivation(); } -void MobileActivator::GetPropertiesFailure( - const std::string& error_name, - std::unique_ptr<base::Value> error_data) { +void MobileActivator::GetPropertiesFailure(const std::string& error_name, + base::Value error_data) { NET_LOG(ERROR) << "MobileActivator GetProperties failed for " << NetworkPathId(service_path_) << " Error: " << error_name; }
diff --git a/chrome/browser/ash/mobile/mobile_activator.h b/chrome/browser/ash/mobile/mobile_activator.h index 8704d465..87ba69f 100644 --- a/chrome/browser/ash/mobile/mobile_activator.h +++ b/chrome/browser/ash/mobile/mobile_activator.h
@@ -18,6 +18,10 @@ #include "base/values.h" #include "chromeos/ash/components/network/network_state_handler_observer.h" +namespace base { +class Value; +} // namespace base + namespace ash { class NetworkState; @@ -152,7 +156,7 @@ void OnShuttingDown() override; void GetPropertiesFailure(const std::string& error_name, - std::unique_ptr<base::Value> error_data); + base::Value error_data); // Handles the signal that the payment portal has finished loading. void HandlePortalLoaded(bool success); // Handles the signal that the user has finished with the portal.
diff --git a/chrome/browser/ash/net/network_diagnostics/dns_resolver_present_routine_unittest.cc b/chrome/browser/ash/net/network_diagnostics/dns_resolver_present_routine_unittest.cc index 7ff2832..092a8ad 100644 --- a/chrome/browser/ash/net/network_diagnostics/dns_resolver_present_routine_unittest.cc +++ b/chrome/browser/ash/net/network_diagnostics/dns_resolver_present_routine_unittest.cc
@@ -73,15 +73,16 @@ // Set up the IP config base::Value::Dict ip_config_properties; - ip_config_properties.Set(shill::kMethodProperty, base::Value(type)); - ip_config_properties.Set(shill::kNameServersProperty, dns_servers.Clone()); + ip_config_properties.Set(shill::kMethodProperty, type); + ip_config_properties.Set(shill::kNameServersProperty, + base::Value(dns_servers.Clone())); helper()->ip_config_test()->AddIPConfig( - kIPConfigPath, base::Value(std::move(ip_config_properties))); + kIPConfigPath, base::Value(ip_config_properties.Clone())); std::string wifi_device_path = helper()->device_test()->GetDevicePathForType(shill::kTypeWifi); helper()->device_test()->SetDeviceProperty( wifi_device_path, shill::kIPConfigsProperty, - base::Value(std::move(ip_config_properties)), + base::Value(ip_config_properties.Clone()), /*notify_changed=*/true); SetServiceProperty(wifi_path(), shill::kIPConfigProperty, base::Value(kIPConfigPath));
diff --git a/chrome/browser/ash/net/network_diagnostics/network_diagnostics_unittest.cc b/chrome/browser/ash/net/network_diagnostics/network_diagnostics_unittest.cc index 0057e33..ab3e958 100644 --- a/chrome/browser/ash/net/network_diagnostics/network_diagnostics_unittest.cc +++ b/chrome/browser/ash/net/network_diagnostics/network_diagnostics_unittest.cc
@@ -106,9 +106,9 @@ // Set up the IP v4 config base::Value::Dict ip_config_v4_properties; ip_config_v4_properties.Set(shill::kNameServersProperty, - dns_servers.Clone()); + base::Value(dns_servers.Clone())); helper()->ip_config_test()->AddIPConfig( - kIPv4ConfigPath, base::Value(std::move(ip_config_v4_properties))); + kIPv4ConfigPath, base::Value(ip_config_v4_properties.Clone())); std::string wifi_device_path = helper()->device_test()->GetDevicePathForType(shill::kTypeWifi); helper()->device_test()->SetDeviceProperty(
diff --git a/chrome/browser/ash/net/network_pref_state_observer_unittest.cc b/chrome/browser/ash/net/network_pref_state_observer_unittest.cc index de6e0f4..e4ee978 100644 --- a/chrome/browser/ash/net/network_pref_state_observer_unittest.cc +++ b/chrome/browser/ash/net/network_pref_state_observer_unittest.cc
@@ -105,8 +105,8 @@ base::Value::Dict proxy_config; proxy_config.Set("mode", ProxyPrefs::kPacScriptProxyModeName); proxy_config.Set("pac_url", "http://proxy"); - profile->GetPrefs()->SetDict(proxy_config::prefs::kProxy, - std::move(proxy_config)); + profile->GetPrefs()->Set(proxy_config::prefs::kProxy, + base::Value(std::move(proxy_config))); base::RunLoop().RunUntilIdle(); // Mode should now be MODE_PAC_SCRIPT.
diff --git a/chrome/browser/ash/note_taking_helper_unittest.cc b/chrome/browser/ash/note_taking_helper_unittest.cc index f789d1d1..d05cc88d 100644 --- a/chrome/browser/ash/note_taking_helper_unittest.cc +++ b/chrome/browser/ash/note_taking_helper_unittest.cc
@@ -309,10 +309,10 @@ extensions::DictionaryBuilder() .Set("scripts", extensions::ListBuilder() .Append("background.js") - .BuildList()) - .BuildDict()) - .BuildDict()) - .BuildDict(); + .Build()) + .Build()) + .Build()) + .Build(); if (action_handlers) manifest.Set("action_handlers", std::move(*action_handlers));
diff --git a/chrome/browser/ash/platform_keys/key_permissions/arc_key_permissions_manager_delegate_unittest.cc b/chrome/browser/ash/platform_keys/key_permissions/arc_key_permissions_manager_delegate_unittest.cc index 017d48d..96e11bdc 100644 --- a/chrome/browser/ash/platform_keys/key_permissions/arc_key_permissions_manager_delegate_unittest.cc +++ b/chrome/browser/ash/platform_keys/key_permissions/arc_key_permissions_manager_delegate_unittest.cc
@@ -104,8 +104,7 @@ void SetCorporateUsageInPolicyForPackage(const std::string& package_name, bool allowed) { base::Value::Dict corporate_key_usage; - corporate_key_usage.SetByDottedPath("allowCorporateKeyUsage", - base::Value(allowed)); + corporate_key_usage.SetByDottedPath("allowCorporateKeyUsage", allowed); base::Value::Dict policy_value; policy_value.Set(package_name, base::Value(std::move(corporate_key_usage))); @@ -113,7 +112,7 @@ policy::PolicyMap policy_map; policy_map.Set(policy::key::kKeyPermissions, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_PLATFORM, - base::Value(std::move(policy_value)), nullptr); + base::Value(policy_value.Clone()), nullptr); policy_provider_->UpdateChromePolicy(policy_map); }
diff --git a/chrome/browser/ash/policy/core/device_local_account_browsertest.cc b/chrome/browser/ash/policy/core/device_local_account_browsertest.cc index e311f9e..1d9127f 100644 --- a/chrome/browser/ash/policy/core/device_local_account_browsertest.cc +++ b/chrome/browser/ash/policy/core/device_local_account_browsertest.cc
@@ -1315,12 +1315,10 @@ embedded_test_server()->StartAcceptingConnections(); // Specify an external data reference for the key::kUserAvatarImage policy. - std::unique_ptr<base::Value::Dict> metadata = - test::ConstructExternalDataReference( - embedded_test_server()->GetURL(kExternalDataPath).spec(), - kExternalData); + base::Value metadata = test::ConstructExternalDataReference( + embedded_test_server()->GetURL(kExternalDataPath).spec(), kExternalData); std::string policy; - base::JSONWriter::Write(*metadata, &policy); + base::JSONWriter::Write(metadata, &policy); device_local_account_policy_.payload().mutable_useravatarimage()->set_value( policy); UploadAndInstallDeviceLocalAccountPolicy(); @@ -1366,7 +1364,7 @@ PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); policy_entry = policies.Get(key::kUserAvatarImage); ASSERT_TRUE(policy_entry); - EXPECT_EQ(*metadata, *policy_entry->value(base::Value::Type::DICT)); + EXPECT_EQ(metadata, *policy_entry->value(base::Value::Type::DICT)); ASSERT_TRUE(policy_entry->external_data_fetcher); // Retrieve the external data via the ProfilePolicyConnector. The retrieval @@ -1404,7 +1402,7 @@ std::string policy; base::JSONWriter::Write( - *test::ConstructExternalDataReference( + test::ConstructExternalDataReference( embedded_test_server() ->GetURL(std::string("/") + ash::test::kUserAvatarImage1RelativePath)
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc index e369e7ae..89ced73 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -1642,8 +1642,8 @@ if (policy.has_tpm_firmware_update_settings()) { policies->Set(key::kTPMFirmwareUpdateSettings, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, - std::move(*(ash::tpm_firmware_update::DecodeSettingsProto( - policy.tpm_firmware_update_settings()))), + ash::tpm_firmware_update::DecodeSettingsProto( + policy.tpm_firmware_update_settings()), nullptr); }
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc index 1f70eb3..86af49d 100644 --- a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc +++ b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc
@@ -67,8 +67,8 @@ ~DevicePolicyDecoderTest() override = default; protected: - std::unique_ptr<base::Value> GetWallpaperDict() const; - std::unique_ptr<base::Value> GetBluetoothServiceAllowedList() const; + base::Value GetWallpaperDict() const; + base::Value GetBluetoothServiceAllowedList() const; void DecodeDevicePolicyTestHelper( const em::ChromeDeviceSettingsProto& device_policy, const std::string& policy_path, @@ -78,20 +78,19 @@ const std::string& policy_path) const; }; -std::unique_ptr<base::Value> DevicePolicyDecoderTest::GetWallpaperDict() const { +base::Value DevicePolicyDecoderTest::GetWallpaperDict() const { base::Value::Dict dict; dict.Set(kWallpaperUrlPropertyName, kWallpaperUrlPropertyValue); dict.Set(kWallpaperHashPropertyName, kWallpaperHashPropertyValue); - return std::make_unique<base::Value>(std::move(dict)); + return base::Value(std::move(dict)); } -std::unique_ptr<base::Value> -DevicePolicyDecoderTest::GetBluetoothServiceAllowedList() const { +base::Value DevicePolicyDecoderTest::GetBluetoothServiceAllowedList() const { base::Value::List list; list.Append(kValidBluetoothServiceUUID4); list.Append(kValidBluetoothServiceUUID8); list.Append(kValidBluetoothServiceUUID32); - return std::make_unique<base::Value>(std::move(list)); + return base::Value(std::move(list)); } void DevicePolicyDecoderTest::DecodeDevicePolicyTestHelper( @@ -168,7 +167,7 @@ kWallpaperJsonUnknownProperty, key::kDeviceWallpaperImage, &error); std::string localized_error = l10n_util::GetStringFUTF8( IDS_POLICY_PROTO_PARSING_ERROR, base::UTF8ToUTF16(error)); - EXPECT_EQ(*GetWallpaperDict(), decoded_json.value()); + EXPECT_EQ(GetWallpaperDict(), decoded_json.value()); EXPECT_EQ( "Policy parsing error: Dropped unknown properties: Unknown property: " "unknown-field (at DeviceWallpaperImage)", @@ -179,7 +178,7 @@ std::string error; absl::optional<base::Value> decoded_json = DecodeJsonStringAndNormalize( kWallpaperJson, key::kDeviceWallpaperImage, &error); - EXPECT_EQ(*GetWallpaperDict(), decoded_json.value()); + EXPECT_EQ(GetWallpaperDict(), decoded_json.value()); EXPECT_TRUE(error.empty()); } @@ -370,7 +369,7 @@ absl::optional<base::Value> decoded_json = DecodeJsonStringAndNormalize( kValidBluetoothServiceUUIDList, key::kDeviceAllowedBluetoothServices, &error); - EXPECT_EQ(*GetBluetoothServiceAllowedList(), decoded_json.value()); + EXPECT_EQ(GetBluetoothServiceAllowedList(), decoded_json.value()); EXPECT_TRUE(error.empty()); }
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base.cc b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base.cc index 27c1f9f1..fa7e95a 100644 --- a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base.cc +++ b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base.cc
@@ -45,7 +45,7 @@ // external data even if no |max_size| was specified in policy_templates.json. int g_max_external_data_size_for_testing = 0; -// Keys for 'DictionaryValue' objects +// Keys for 'Value::Dict' objects const char kUrlKey[] = "url"; const char kHashKey[] = "hash"; const char kCustomIconKey[] = "custom_icon";
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.cc b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.cc index 474dcbf..b5834d9d 100644 --- a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.cc +++ b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.cc
@@ -31,7 +31,7 @@ namespace policy { namespace { -// Keys for the 'Value' objects +// Keys for 'Value::Dict' objects const char kUrlKey[] = "url"; const char kHashKey[] = "hash"; } // namespace @@ -48,14 +48,13 @@ std::move(done_callback).Run(); } -std::unique_ptr<base::Value::Dict> ConstructExternalDataReference( - const std::string& url, - const std::string& data) { +base::Value ConstructExternalDataReference(const std::string& url, + const std::string& data) { const std::string hash = crypto::SHA256HashString(data); - auto metadata = std::make_unique<base::Value::Dict>(); - metadata->Set(kUrlKey, url); - metadata->Set(kHashKey, base::HexEncode(hash.c_str(), hash.size())); - return metadata; + base::Value::Dict metadata; + metadata.Set(kUrlKey, url); + metadata.Set(kHashKey, base::HexEncode(hash.c_str(), hash.size())); + return base::Value(std::move(metadata)); } std::string ConstructExternalDataPolicy( @@ -75,7 +74,7 @@ std::string policy; EXPECT_TRUE(base::JSONWriter::Write( - *ConstructExternalDataReference(url, external_data), &policy)); + ConstructExternalDataReference(url, external_data), &policy)); return policy; }
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.h b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.h index 94377433..43643f9 100644 --- a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.h +++ b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.h
@@ -10,7 +10,10 @@ #include "base/callback_forward.h" #include "base/files/file_path.h" -#include "base/values.h" + +namespace base { +class Value; +} namespace net { namespace test_server { @@ -20,8 +23,6 @@ namespace policy { -class CloudPolicyCore; - namespace test { // Passes |data| to |destination| and invokes |done_callback| to indicate that @@ -34,9 +35,8 @@ // Constructs a value that points a policy referencing external data at |url| // and sets the expected hash of the external data to that of |data|. -std::unique_ptr<base::Value::Dict> ConstructExternalDataReference( - const std::string& url, - const std::string& data); +base::Value ConstructExternalDataReference(const std::string& url, + const std::string& data); // Constructs the external data policy from the content of the file located on // |external_data_path|. @@ -44,15 +44,6 @@ const net::test_server::EmbeddedTestServer& test_server, const std::string& external_data_path); -// TODO(bartfab): Makes an arbitrary |policy| in |core| reference external data -// as specified in |metadata|. This is only done because there are no policies -// that reference external data yet. Once the first such policy is added, it -// will be sufficient to set its value to |metadata| and this method should be -// removed. -void SetExternalDataReference(CloudPolicyCore* core, - const std::string& policy, - std::unique_ptr<base::Value::Dict> metadata); - } // namespace test } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_unittest.cc b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_unittest.cc index 75cc8b6..6f7f898d 100644 --- a/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_unittest.cc +++ b/chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_unittest.cc
@@ -175,10 +175,10 @@ base::Value CloudExternalDataManagerBaseTest::ConstructMetadata( const std::string& url, const std::string& hash) { - base::Value metadata(base::Value::Type::DICTIONARY); - metadata.SetStringKey("url", url); - metadata.SetStringKey("hash", base::HexEncode(hash.c_str(), hash.size())); - return metadata; + base::Value::Dict metadata; + metadata.Set("url", url); + metadata.Set("hash", base::HexEncode(hash.c_str(), hash.size())); + return base::Value(std::move(metadata)); } void CloudExternalDataManagerBaseTest::AddMetadataToWebAppPolicyValue(
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc b/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc index 1e55dad3..fa49967 100644 --- a/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc +++ b/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
@@ -83,7 +83,7 @@ ASSERT_TRUE(base::ReadFileToString( test_data_dir.Append("chromeos").Append(file_name), policy_data)); base::JSONWriter::Write( - *test::ConstructExternalDataReference(url, *policy_data), policy); + test::ConstructExternalDataReference(url, *policy_data), policy); } } // namespace
diff --git a/chrome/browser/ash/policy/external_data/user_cloud_external_data_manager_browsertest.cc b/chrome/browser/ash/policy/external_data/user_cloud_external_data_manager_browsertest.cc index 746443c..41c8ad2 100644 --- a/chrome/browser/ash/policy/external_data/user_cloud_external_data_manager_browsertest.cc +++ b/chrome/browser/ash/policy/external_data/user_cloud_external_data_manager_browsertest.cc
@@ -68,7 +68,7 @@ } std::string external_data_; - std::unique_ptr<base::Value::Dict> metadata_; + base::Value metadata_; }; IN_PROC_BROWSER_TEST_F(UserCloudExternalDataManagerTest, FetchExternalData) { @@ -81,7 +81,7 @@ ASSERT_TRUE(profile); std::string value; - ASSERT_TRUE(base::JSONWriter::Write(*metadata_, &value)); + ASSERT_TRUE(base::JSONWriter::Write(metadata_, &value)); enterprise_management::CloudPolicySettings policy; policy.mutable_wallpaperimage()->set_value(value); user_policy_helper()->SetPolicyAndWait(policy, profile); @@ -104,7 +104,7 @@ PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); const PolicyMap::Entry* policy_entry = policies.Get(key::kWallpaperImage); ASSERT_TRUE(policy_entry); - EXPECT_EQ(*metadata_, *policy_entry->value(base::Value::Type::DICT)); + EXPECT_EQ(metadata_, *policy_entry->value(base::Value::Type::DICT)); ASSERT_TRUE(policy_entry->external_data_fetcher); base::RunLoop run_loop;
diff --git a/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc index a6b9083..c3659f1 100644 --- a/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc +++ b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc
@@ -54,7 +54,7 @@ void SetAutoUpdateMode(AutoUpdateMode auto_update_mode) { base::Value::Dict dict; dict.Set(ash::tpm_firmware_update::kSettingsKeyAutoUpdateMode, - base::Value(static_cast<int>(auto_update_mode))); + static_cast<int>(auto_update_mode)); scoped_testing_cros_settings_.device_settings()->Set( ash::kTPMFirmwareUpdateSettings, base::Value(std::move(dict))); base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ash/policy/off_hours/off_hours_proto_parser.h b/chrome/browser/ash/policy/off_hours/off_hours_proto_parser.h index 81fab000..3e5cb97 100644 --- a/chrome/browser/ash/policy/off_hours/off_hours_proto_parser.h +++ b/chrome/browser/ash/policy/off_hours/off_hours_proto_parser.h
@@ -39,7 +39,7 @@ absl::optional<std::string> ExtractTimezoneFromProto( const enterprise_management::DeviceOffHoursProto& container); -// Return DictionaryValue in format: +// Return Value::Dict in format: // { "timezone" : string, // "intervals" : list of "OffHours" Intervals, // "ignored_policy_proto_tags" : integer list }
diff --git a/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc b/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc index 20c1d0f..a02df85d 100644 --- a/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc +++ b/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc
@@ -265,7 +265,7 @@ return policy_map; } - base::Value::Dict CreateComplianceReport( + base::Value CreateComplianceReport( std::set<std::string> noncompliant_packages) { base::Value::List details; @@ -278,7 +278,7 @@ base::Value::Dict compliance_report; compliance_report.Set("nonComplianceDetails", std::move(details)); - return compliance_report; + return base::Value(std::move(compliance_report)); } content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc index eebdd25..1b32183 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
@@ -136,9 +136,8 @@ base::Value(device_path)); base::Value::Dict ip_config_properties; ip_config_properties.Set(shill::kAddressProperty, - base::Value(network_data.ip_address)); - ip_config_properties.Set(shill::kGatewayProperty, - base::Value(network_data.gateway)); + network_data.ip_address); + ip_config_properties.Set(shill::kGatewayProperty, network_data.gateway); const std::string kIPConfigPath = base::StrCat({"test_ip_config", network_data.guid}); ip_config_client->AddIPConfig(
diff --git a/chrome/browser/ash/policy/status_collector/activity_storage.cc b/chrome/browser/ash/policy/status_collector/activity_storage.cc index 2797539..38d53622b 100644 --- a/chrome/browser/ash/policy/status_collector/activity_storage.cc +++ b/chrome/browser/ash/policy/status_collector/activity_storage.cc
@@ -77,7 +77,7 @@ if (duration <= 0) return; const std::string key = MakeActivityPeriodPrefKey(day_key, activity_id); - copy.Set(key, base::saturated_cast<int>(duration)); + copy.SetByDottedPath(key, base::saturated_cast<int>(duration)); }, std::ref(copy), min_day_key, max_day_key));
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc index 6f7dea6..ee33574 100644 --- a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc +++ b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
@@ -3936,13 +3936,12 @@ base::Value(kShillFakeProfilePath)); if (strlen(fake_network.address) > 0) { // Set the IP config. - base::DictionaryValue ip_config_properties; - ip_config_properties.SetKey(shill::kAddressProperty, - base::Value(fake_network.address)); - ip_config_properties.SetKey(shill::kGatewayProperty, - base::Value(fake_network.gateway)); + base::Value::Dict ip_config_properties; + ip_config_properties.Set(shill::kAddressProperty, fake_network.address); + ip_config_properties.Set(shill::kGatewayProperty, fake_network.gateway); const std::string kIPConfigPath = "test_ip_config"; - ip_config_client->AddIPConfig(kIPConfigPath, ip_config_properties); + ip_config_client->AddIPConfig( + kIPConfigPath, base::Value(std::move(ip_config_properties))); service_client->SetServiceProperty(fake_network.name, shill::kIPConfigProperty, base::Value(kIPConfigPath));
diff --git a/chrome/browser/ash/preferences.cc b/chrome/browser/ash/preferences.cc index fba03e8b..83e5eadb 100644 --- a/chrome/browser/ash/preferences.cc +++ b/chrome/browser/ash/preferences.cc
@@ -517,6 +517,8 @@ registry->RegisterBooleanPref(prefs::kSyncOobeCompleted, false); + registry->RegisterBooleanPref(prefs::kRecordArcAppSyncMetrics, false); + registry->RegisterBooleanPref(::prefs::kTPMFirmwareUpdateCleanupDismissed, false);
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc index b3120a9..109216c 100644 --- a/chrome/browser/ash/settings/device_settings_provider.cc +++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -968,9 +968,8 @@ if (policy.has_tpm_firmware_update_settings()) { new_values_cache->SetValue(kTPMFirmwareUpdateSettings, - base::Value::FromUniquePtrValue( - tpm_firmware_update::DecodeSettingsProto( - policy.tpm_firmware_update_settings()))); + tpm_firmware_update::DecodeSettingsProto( + policy.tpm_firmware_update_settings())); } if (policy.has_device_minimum_version()) {
diff --git a/chrome/browser/ash/tpm_firmware_update.cc b/chrome/browser/ash/tpm_firmware_update.cc index a10db25d..bfb1438b 100644 --- a/chrome/browser/ash/tpm_firmware_update.cc +++ b/chrome/browser/ash/tpm_firmware_update.cc
@@ -63,25 +63,24 @@ "allow-user-initiated-preserve-device-state"; const char kSettingsKeyAutoUpdateMode[] = "auto-update-mode"; -std::unique_ptr<base::Value> DecodeSettingsProto( +base::Value DecodeSettingsProto( const enterprise_management::TPMFirmwareUpdateSettingsProto& settings) { base::Value::Dict result; + if (settings.has_allow_user_initiated_powerwash()) { result.Set(kSettingsKeyAllowPowerwash, - base::Value(settings.allow_user_initiated_powerwash())); + settings.allow_user_initiated_powerwash()); } if (settings.has_allow_user_initiated_preserve_device_state()) { - result.Set( - kSettingsKeyAllowPreserveDeviceState, - base::Value(settings.allow_user_initiated_preserve_device_state())); + result.Set(kSettingsKeyAllowPreserveDeviceState, + settings.allow_user_initiated_preserve_device_state()); } if (settings.has_auto_update_mode()) { - result.Set(kSettingsKeyAutoUpdateMode, - base::Value(settings.auto_update_mode())); + result.Set(kSettingsKeyAutoUpdateMode, settings.auto_update_mode()); } - return std::make_unique<base::Value>(std::move(result)); + return base::Value(std::move(result)); } // AvailabilityChecker tracks TPM firmware update availability information
diff --git a/chrome/browser/ash/tpm_firmware_update.h b/chrome/browser/ash/tpm_firmware_update.h index fb47182f..c1b37d9 100644 --- a/chrome/browser/ash/tpm_firmware_update.h +++ b/chrome/browser/ash/tpm_firmware_update.h
@@ -10,7 +10,10 @@ #include "base/callback_forward.h" #include "base/time/time.h" -#include "base/values.h" + +namespace base { +class Value; +} namespace enterprise_management { class TPMFirmwareUpdateSettingsProto; @@ -40,7 +43,7 @@ extern const char kSettingsKeyAutoUpdateMode[]; // Decodes the TPM firmware update settings into base::Value representation. -std::unique_ptr<base::Value> DecodeSettingsProto( +base::Value DecodeSettingsProto( const enterprise_management::TPMFirmwareUpdateSettingsProto& settings); // Check what update modes are allowed. The |timeout| parameter determines how
diff --git a/chrome/browser/ash/tpm_firmware_update_unittest.cc b/chrome/browser/ash/tpm_firmware_update_unittest.cc index f34a298..41b3fe3f 100644 --- a/chrome/browser/ash/tpm_firmware_update_unittest.cc +++ b/chrome/browser/ash/tpm_firmware_update_unittest.cc
@@ -40,12 +40,14 @@ enterprise_management:: TPMFirmwareUpdateSettingsProto_AutoUpdateMode_USER_ACKNOWLEDGMENT); auto dict = DecodeSettingsProto(settings); - ASSERT_TRUE(dict); - EXPECT_THAT(dict->FindBoolKey("allow-user-initiated-powerwash"), + ASSERT_TRUE(dict.is_dict()); + EXPECT_THAT(dict.GetDict().FindBool("allow-user-initiated-powerwash"), Optional(true)); - EXPECT_THAT(dict->FindBoolKey("allow-user-initiated-preserve-device-state"), - Optional(true)); - int update_mode_value = dict->FindIntKey("auto-update-mode").value_or(0); + EXPECT_THAT( + dict.GetDict().FindBool("allow-user-initiated-preserve-device-state"), + Optional(true)); + int update_mode_value = + dict.GetDict().FindInt("auto-update-mode").value_or(0); EXPECT_EQ(2, update_mode_value); } @@ -292,10 +294,9 @@ void SetPolicy(const std::set<Mode>& modes) { base::Value::Dict dict; - dict.Set(kSettingsKeyAllowPowerwash, - base::Value(modes.count(Mode::kPowerwash) > 0)); + dict.Set(kSettingsKeyAllowPowerwash, modes.count(Mode::kPowerwash) > 0); dict.Set(kSettingsKeyAllowPreserveDeviceState, - base::Value(modes.count(Mode::kPreserveDeviceState) > 0)); + modes.count(Mode::kPreserveDeviceState) > 0); cros_settings_test_helper_.Set(kTPMFirmwareUpdateSettings, base::Value(std::move(dict))); }
diff --git a/chrome/browser/background/background_application_list_model_unittest.cc b/chrome/browser/background/background_application_list_model_unittest.cc index 83af0e8..f58088ed 100644 --- a/chrome/browser/background/background_application_list_model_unittest.cc +++ b/chrome/browser/background/background_application_list_model_unittest.cc
@@ -87,23 +87,20 @@ static scoped_refptr<Extension> CreateExtension( const std::string& name, bool background_permission) { - base::DictionaryValue manifest; - manifest.SetStringPath(extensions::manifest_keys::kVersion, "1.0.0.0"); - manifest.SetIntPath(extensions::manifest_keys::kManifestVersion, 2); - manifest.SetStringPath(extensions::manifest_keys::kName, name); - base::ListValue permissions; + base::Value::Dict manifest; + manifest.Set(extensions::manifest_keys::kVersion, "1.0.0.0"); + manifest.Set(extensions::manifest_keys::kManifestVersion, 2); + manifest.Set(extensions::manifest_keys::kName, name); + base::Value::List permissions; if (background_permission) { permissions.Append("background"); } - manifest.SetKey(extensions::manifest_keys::kPermissions, - std::move(permissions)); + manifest.Set(extensions::manifest_keys::kPermissions, std::move(permissions)); std::string error; - scoped_refptr<Extension> extension; - - extension = Extension::Create( + scoped_refptr<Extension> extension = Extension::Create( bogus_file_pathname(name), extensions::mojom::ManifestLocation::kInternal, - manifest.GetDict(), Extension::NO_FLAGS, &error); + manifest, Extension::NO_FLAGS, &error); // Cannot ASSERT_* here because that attempts an illegitimate return. // Cannot EXPECT_NE here because that assumes non-pointers unlike EXPECT_EQ
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc index a6a2b9d..957dd05b 100644 --- a/chrome/browser/background/background_contents_service.cc +++ b/chrome/browser/background/background_contents_service.cc
@@ -229,13 +229,13 @@ } // namespace // Keys for the information we store about individual BackgroundContents in -// prefs. There is one top-level DictionaryValue (stored at +// prefs. There is one top-level base::Value::Dict (stored at // prefs::kRegisteredBackgroundContents). Information about each -// BackgroundContents is stored under that top-level DictionaryValue, keyed +// BackgroundContents is stored under that top-level base::Value::Dict, keyed // by the parent application ID for easy lookup. // // kRegisteredBackgroundContents: -// DictionaryValue { +// base::Value::Dict { // <appid_1>: { "url": <url1>, "name": <frame_name> }, // <appid_2>: { "url": <url2>, "name": <frame_name> }, // ... etc ...
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc index 5c83e0a2..ec8daad 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -180,27 +180,25 @@ return; } - base::Value* roots = bookmarks_.FindDictKey(BookmarkCodec::kRootsKey); + base::Value::Dict* roots = + bookmarks_.GetDict().FindDict(BookmarkCodec::kRootsKey); DCHECK(roots); - base::Value* root_folder_value = - roots->FindDictKey(BookmarkCodec::kBookmarkBarFolderNameKey); - base::Value* other_folder_value = - roots->FindDictKey(BookmarkCodec::kOtherBookmarkFolderNameKey); - base::Value* mobile_folder_value = - roots->FindDictKey(BookmarkCodec::kMobileBookmarkFolderNameKey); + base::Value::Dict* root_folder_value = + roots->FindDict(BookmarkCodec::kBookmarkBarFolderNameKey); + base::Value::Dict* other_folder_value = + roots->FindDict(BookmarkCodec::kOtherBookmarkFolderNameKey); + base::Value::Dict* mobile_folder_value = + roots->FindDict(BookmarkCodec::kMobileBookmarkFolderNameKey); DCHECK(root_folder_value); DCHECK(other_folder_value); DCHECK(mobile_folder_value); IncrementIndent(); - if (!WriteNode(*static_cast<base::DictionaryValue*>(root_folder_value), - BookmarkNode::BOOKMARK_BAR) || - !WriteNode(*static_cast<base::DictionaryValue*>(other_folder_value), - BookmarkNode::OTHER_NODE) || - !WriteNode(*static_cast<base::DictionaryValue*>(mobile_folder_value), - BookmarkNode::MOBILE)) { + if (!WriteNode(*root_folder_value, BookmarkNode::BOOKMARK_BAR) || + !WriteNode(*other_folder_value, BookmarkNode::OTHER_NODE) || + !WriteNode(*mobile_folder_value, BookmarkNode::MOBILE)) { NotifyOnFinish(BookmarksExportObserver::Result::kCouldNotWriteNodes); return; } @@ -313,13 +311,12 @@ } // Writes the node and all its children, returning true on success. - bool WriteNode(const base::Value& value, BookmarkNode::Type folder_type) { - DCHECK(value.is_dict()); - const std::string* title_ptr = value.FindStringKey(BookmarkCodec::kNameKey); + bool WriteNode(const base::Value::Dict& value, + BookmarkNode::Type folder_type) { + const std::string* title_ptr = value.FindString(BookmarkCodec::kNameKey); const std::string* date_added_string = - value.FindStringKey(BookmarkCodec::kDateAddedKey); - const std::string* type_string = - value.FindStringKey(BookmarkCodec::kTypeKey); + value.FindString(BookmarkCodec::kDateAddedKey); + const std::string* type_string = value.FindString(BookmarkCodec::kTypeKey); if (!title_ptr || !date_added_string || !type_string || (*type_string != BookmarkCodec::kTypeURL && *type_string != BookmarkCodec::kTypeFolder)) { @@ -329,8 +326,7 @@ std::string title = *title_ptr; if (*type_string == BookmarkCodec::kTypeURL) { - const std::string* url_string = - value.FindStringKey(BookmarkCodec::kURLKey); + const std::string* url_string = value.FindString(BookmarkCodec::kURLKey); if (!url_string) { NOTREACHED(); return false; @@ -362,9 +358,9 @@ // Folder. const std::string* last_modified_date = - value.FindStringKey(BookmarkCodec::kDateModifiedKey); - const base::Value* child_values = - value.FindListKey(BookmarkCodec::kChildrenKey); + value.FindString(BookmarkCodec::kDateModifiedKey); + const base::Value::List* child_values = + value.FindList(BookmarkCodec::kChildrenKey); if (!last_modified_date || !child_values) { NOTREACHED(); return false; @@ -398,13 +394,14 @@ } // Write the children. - for (const base::Value& child_value : child_values->GetList()) { + for (const base::Value& child_value : *child_values) { if (!child_value.is_dict()) { NOTREACHED(); return false; } - if (!WriteNode(child_value, BookmarkNode::FOLDER)) + if (!WriteNode(child_value.GetDict(), BookmarkNode::FOLDER)) { return false; + } } if (folder_type != BookmarkNode::OTHER_NODE && folder_type != BookmarkNode::MOBILE) {
diff --git a/chrome/browser/browsing_data/counters/hosted_apps_counter_unittest.cc b/chrome/browser/browsing_data/counters/hosted_apps_counter_unittest.cc index 4b3c5bb..b712814 100644 --- a/chrome/browser/browsing_data/counters/hosted_apps_counter_unittest.cc +++ b/chrome/browser/browsing_data/counters/hosted_apps_counter_unittest.cc
@@ -23,6 +23,7 @@ #include "extensions/common/extension_builder.h" #include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace { @@ -42,7 +43,7 @@ // Adding and removing apps and extensions. ---------------------------------- std::string AddExtension() { - return AddItem(base::GenerateGUID(), /*app_manifest=*/nullptr); + return AddItem(base::GenerateGUID(), /*app_manifest=*/absl::nullopt); } std::string AddPackagedApp() { @@ -70,15 +71,16 @@ } std::string AddItem(const std::string& name, - std::unique_ptr<base::Value> app_manifest) { + absl::optional<base::Value::Dict> app_manifest) { DictionaryBuilder manifest_builder; manifest_builder .Set("manifest_version", 2) .Set("name", name) .Set("version", "1"); - if (app_manifest) - manifest_builder.Set("app", std::move(app_manifest)); + if (app_manifest) { + manifest_builder.Set("app", std::move(*app_manifest)); + } scoped_refptr<const extensions::Extension> item = extensions::ExtensionBuilder()
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/cleanup/extension_cleanup_handler_browsertest.cc b/chrome/browser/chromeos/extensions/login_screen/login/cleanup/extension_cleanup_handler_browsertest.cc index 20a0260..98c561a 100644 --- a/chrome/browser/chromeos/extensions/login_screen/login/cleanup/extension_cleanup_handler_browsertest.cc +++ b/chrome/browser/chromeos/extensions/login_screen/login/cleanup/extension_cleanup_handler_browsertest.cc
@@ -134,13 +134,12 @@ extensions::ExtensionService* extension_service = extensions::ExtensionSystem::Get(GetActiveUserProfile()) ->extension_service(); - std::unique_ptr<base::DictionaryValue> manifest( - extensions::DictionaryBuilder() - .Set("name", "Foo") - .Set("description", "Bar") - .Set("manifest_version", 2) - .Set("version", "1.0") - .Build()); + base::Value::Dict manifest(extensions::DictionaryBuilder() + .Set("name", "Foo") + .Set("description", "Bar") + .Set("manifest_version", 2) + .Set("version", "1.0") + .Build()); auto observer = GetTestExtensionRegistryObserver(extension_id); scoped_refptr<const extensions::Extension> extension =
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java index 8ecb3e9..c0fa8ef5 100644 --- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java +++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
@@ -8,7 +8,6 @@ import android.content.ComponentName; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.os.Build; import android.view.View; import androidx.fragment.app.FragmentActivity; @@ -205,9 +204,7 @@ * Retrieves the user's preferred locale from the app's configurations. */ private Locale getPreferredLocale() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? mActivity.getResources().getConfiguration().getLocales().get(0) - : mActivity.getResources().getConfiguration().locale; + return mActivity.getResources().getConfiguration().getLocales().get(0); } private String addQuotes(String text) {
diff --git a/chrome/browser/dips/dips_utils.cc b/chrome/browser/dips/dips_utils.cc index c543a99..a8ef2f9 100644 --- a/chrome/browser/dips/dips_utils.cc +++ b/chrome/browser/dips/dips_utils.cc
@@ -27,14 +27,18 @@ } bool TimestampRange::IsNullOrWithin(TimestampRange other) const { - if (!first.has_value()) { - return true; + if (first.has_value()) { + if (!other.first.has_value() || other.first.value() > first.value()) { + return false; + } } - if (!other.first.has_value()) { - return false; + if (last.has_value()) { + if (!other.last.has_value() || other.last.value() < last.value()) { + return false; + } } - return first.value() >= other.first.value() && - last.value() <= other.last.value(); + + return true; } std::ostream& operator<<(std::ostream& os, absl::optional<base::Time> time) {
diff --git a/chrome/browser/dips/dips_utils_unittest.cc b/chrome/browser/dips/dips_utils_unittest.cc index a09003bf..76b0aa0 100644 --- a/chrome/browser/dips/dips_utils_unittest.cc +++ b/chrome/browser/dips/dips_utils_unittest.cc
@@ -100,6 +100,27 @@ EXPECT_TRUE(range.IsNullOrWithin(range)); } +// This tests verifies that open-ended ranges work for this IsNullOrWithin. +// TODO(kaklilu): remove this test when we update TimestampRange to not support +// open-ended ranges. +TEST(TimestampRangeTest, IsNullOrWithin_Regression_OpenEndedRanges) { + // Open-end range with lower bound. + TimestampRange inner = {base::Time::FromDoubleT(2), absl::nullopt}; + TimestampRange outer = {base::Time::FromDoubleT(1), absl::nullopt}; + + EXPECT_TRUE(inner.IsNullOrWithin(outer)); + // An open-ended range isn't within an empty range + EXPECT_FALSE(inner.IsNullOrWithin(TimestampRange())); + + // Open-end range with upper bound. + outer = {absl::nullopt, base::Time::FromDoubleT(2)}; + inner = {absl::nullopt, base::Time::FromDoubleT(1)}; + + EXPECT_TRUE(inner.IsNullOrWithin(outer)); + // An open-ended range isn't within an empty range + EXPECT_FALSE(inner.IsNullOrWithin(TimestampRange())); +} + TEST(BucketizeBounceDelayTest, BucketizeBounceDelay) { // any TimeDelta in (-inf, 1s) should return 0 EXPECT_EQ(0, BucketizeBounceDelay(base::Days(-1)));
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc index 317c9fd..327e0e0 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
@@ -35,7 +35,6 @@ namespace keys = extensions::declarative_webrequest_constants; using base::DictionaryValue; -using base::ListValue; using extension_test_util::LoadManifestUnchecked; using helpers::EventResponseDeltas; using testing::HasSubstr; @@ -172,9 +171,8 @@ // Test wrong data type passed. error.clear(); - base::ListValue empty_list; - result = WebRequestAction::Create(nullptr, nullptr, empty_list, &error, - &bad_message); + result = WebRequestAction::Create( + nullptr, nullptr, base::Value(base::Value::List()), &error, &bad_message); EXPECT_TRUE(bad_message); EXPECT_FALSE(result.get());
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc index f6d16d13..23443da 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
@@ -889,7 +889,7 @@ for (const auto& test_case : test_cases) { SCOPED_TRACE(test_case.name); - std::unique_ptr<base::Value> command_dict = + base::Value::Dict command_dict = DictionaryBuilder() .Set("suggested_key", DictionaryBuilder().Set("default", "Ctrl+Shift+P").BuildDict())
diff --git a/chrome/browser/extensions/api/enterprise_networking_attributes/enterprise_networking_attributes_ash_apitest.cc b/chrome/browser/extensions/api/enterprise_networking_attributes/enterprise_networking_attributes_ash_apitest.cc index 8012291..644b46f 100644 --- a/chrome/browser/extensions/api/enterprise_networking_attributes/enterprise_networking_attributes_ash_apitest.cc +++ b/chrome/browser/extensions/api/enterprise_networking_attributes/enterprise_networking_attributes_ash_apitest.cc
@@ -111,12 +111,13 @@ shill_ipconfig_client->AddIPConfig(kWifiIPConfigV6Path, ipconfig_v6_dictionary); - base::ListValue ip_configs; + base::Value::List ip_configs; ip_configs.Append(kWifiIPConfigV4Path); ip_configs.Append(kWifiIPConfigV6Path); - shill_device_client->SetDeviceProperty( - kWifiDevicePath, shill::kIPConfigsProperty, ip_configs, - /*notify_changed=*/false); + shill_device_client->SetDeviceProperty(kWifiDevicePath, + shill::kIPConfigsProperty, + base::Value(std::move(ip_configs)), + /*notify_changed=*/false); shill_service_client->AddService(kWifiServicePath, "wifi_guid", "wifi_network_name", shill::kTypeWifi,
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc index fe1cf78..ea609ff 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
@@ -204,8 +204,9 @@ }; TEST_F(EPKChallengeMachineKeyTest, ExtensionNotAllowed) { - base::Value empty_allowlist(base::Value::Type::LIST); - prefs_->Set(prefs::kAttestationExtensionAllowlist, empty_allowlist); + base::Value::List empty_allowlist; + prefs_->SetList(prefs::kAttestationExtensionAllowlist, + std::move(empty_allowlist)); EXPECT_EQ( ash::attestation::TpmChallengeKeyResult::kExtensionNotAllowedErrorMsg, @@ -215,9 +216,9 @@ TEST_F(EPKChallengeMachineKeyTest, Success) { SetMockTpmChallenger(); - base::Value allowlist(base::Value::Type::LIST); - allowlist.GetList().Append(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionAllowlist, allowlist); + base::Value::List allowlist; + allowlist.Append(extension_->id()); + prefs_->SetList(prefs::kAttestationExtensionAllowlist, std::move(allowlist)); base::Value value( RunFunctionAndReturnSingleResult(func_.get(), CreateArgs(), browser())); @@ -230,9 +231,9 @@ TEST_F(EPKChallengeMachineKeyTest, BadChallengeThenErrorMessageReturned) { SetMockTpmChallengerBadBase64Error(); - base::Value allowlist(base::Value::Type::LIST); - allowlist.GetList().Append(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionAllowlist, allowlist); + base::Value::List allowlist; + allowlist.Append(extension_->id()); + prefs_->SetList(prefs::kAttestationExtensionAllowlist, std::move(allowlist)); base::Value value( RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); @@ -245,9 +246,9 @@ TEST_F(EPKChallengeMachineKeyTest, KeyNotRegisteredByDefault) { SetMockTpmChallenger(); - base::Value allowlist(base::Value::Type::LIST); - allowlist.GetList().Append(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionAllowlist, allowlist); + base::Value::List allowlist; + allowlist.Append(extension_->id()); + prefs_->SetList(prefs::kAttestationExtensionAllowlist, std::move(allowlist)); EXPECT_CALL(*mock_tpm_challenge_key_, BuildResponse) .WillOnce(Invoke(FakeRunCheckNotRegister)); @@ -290,9 +291,9 @@ TEST_F(EPKChallengeUserKeyTest, Success) { SetMockTpmChallenger(); - base::Value allowlist(base::Value::Type::LIST); - allowlist.GetList().Append(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionAllowlist, allowlist); + base::Value::List allowlist; + allowlist.Append(extension_->id()); + prefs_->SetList(prefs::kAttestationExtensionAllowlist, std::move(allowlist)); base::Value value( RunFunctionAndReturnSingleResult(func_.get(), CreateArgs(), browser())); @@ -305,9 +306,9 @@ TEST_F(EPKChallengeUserKeyTest, BadChallengeThenErrorMessageReturned) { SetMockTpmChallengerBadBase64Error(); - base::Value allowlist(base::Value::Type::LIST); - allowlist.GetList().Append(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionAllowlist, allowlist); + base::Value::List allowlist; + allowlist.Append(extension_->id()); + prefs_->SetList(prefs::kAttestationExtensionAllowlist, std::move(allowlist)); base::Value value( RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); @@ -318,8 +319,9 @@ } TEST_F(EPKChallengeUserKeyTest, ExtensionNotAllowedThenErrorMessageReturned) { - base::Value empty_allowlist(base::Value::Type::LIST); - prefs_->Set(prefs::kAttestationExtensionAllowlist, empty_allowlist); + base::Value::List empty_allowlist; + prefs_->SetList(prefs::kAttestationExtensionAllowlist, + std::move(empty_allowlist)); EXPECT_EQ( ash::attestation::TpmChallengeKeyResult::kExtensionNotAllowedErrorMsg, @@ -341,9 +343,10 @@ } void AllowlistExtension() { - base::Value allowlist(base::Value::Type::LIST); + base::Value::List allowlist; allowlist.Append(extension_->id()); - prefs_->Set(prefs::kAttestationExtensionAllowlist, allowlist); + prefs_->SetList(prefs::kAttestationExtensionAllowlist, + std::move(allowlist)); } base::Value::List CreateArgs( @@ -364,7 +367,7 @@ } scoped_refptr<EnterprisePlatformKeysChallengeKeyFunction> func_; - base::ListValue args_; + base::Value::List args_; }; // This test ensures challengeKey propagates algorithm, scope, and registerKey @@ -418,8 +421,9 @@ // This test ensures challengeKey cannot be called by extensions not on the // allow list. TEST_P(EPKChallengeKeyTest, ExtensionNotAllowed) { - base::ListValue empty_allowlist; - prefs_->Set(prefs::kAttestationExtensionAllowlist, empty_allowlist); + base::Value::List empty_allowlist; + prefs_->SetList(prefs::kAttestationExtensionAllowlist, + std::move(empty_allowlist)); auto scope = std::get<0>(GetParam()); auto algorithm_opt = std::get<1>(GetParam());
diff --git a/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc b/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc index 1642f9e..ce3a55b9 100644 --- a/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc +++ b/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
@@ -128,18 +128,14 @@ << e.event_args.size(); return false; } - const base::ListValue* services = nullptr; - { - const base::Value& out = e.event_args[0]; - services = static_cast<const base::ListValue*>(&out); - } + const base::Value::List* services = e.event_args[0].GetIfList(); if (!services) { - *listener << "event's service list argument is not a ListValue"; + *listener << "event's service list argument is not a Value::List"; return false; } - *listener << "number of services is " << services->GetList().size(); + *listener << "number of services is " << services->size(); return static_cast<testing::Matcher<size_t>>(testing::Eq(expected_size_)) - .MatchAndExplain(services->GetList().size(), listener); + .MatchAndExplain(services->size(), listener); } virtual void DescribeTo(::std::ostream* os) const {
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_api.cc b/chrome/browser/extensions/api/settings_private/settings_private_api.cc index 7d3aec4..3fa7a77 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_api.cc +++ b/chrome/browser/extensions/api/settings_private/settings_private_api.cc
@@ -66,8 +66,7 @@ SettingsPrivateDelegate* delegate = SettingsPrivateDelegateFactory::GetForBrowserContext(browser_context()); DCHECK(delegate); - return RespondNow( - OneArgument(base::Value::FromUniquePtrValue(delegate->GetAllPrefs()))); + return RespondNow(OneArgument(base::Value(delegate->GetAllPrefs()))); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc b/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc index 68e5e77..24a4ffb 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc +++ b/chrome/browser/extensions/api/settings_private/settings_private_delegate.cc
@@ -38,17 +38,17 @@ return base::Value(pref->ToValue()); } -std::unique_ptr<base::Value> SettingsPrivateDelegate::GetAllPrefs() { - std::unique_ptr<base::ListValue> prefs(new base::ListValue()); +base::Value::List SettingsPrivateDelegate::GetAllPrefs() { + base::Value::List prefs; const TypedPrefMap& keys = prefs_util_->GetAllowlistedKeys(); for (const auto& it : keys) { base::Value pref = GetPref(it.first); if (!pref.is_none()) - prefs->Append(std::move(pref)); + prefs.Append(std::move(pref)); } - return std::move(prefs); + return prefs; } settings_private::SetPrefResult SettingsPrivateDelegate::SetPref(
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_delegate.h b/chrome/browser/extensions/api/settings_private/settings_private_delegate.h index 78fd94a..03b231e9 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_delegate.h +++ b/chrome/browser/extensions/api/settings_private/settings_private_delegate.h
@@ -46,7 +46,7 @@ base::Value GetPref(const std::string& name); // Gets the values of all allowlisted prefs. - virtual std::unique_ptr<base::Value> GetAllPrefs(); + virtual base::Value::List GetAllPrefs(); // Gets the value. virtual std::unique_ptr<base::Value> GetDefaultZoom();
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 45009df..5b5bccb7 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -36,6 +36,7 @@ #include "chrome/browser/extensions/active_tab_permission_granter.h" #include "chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h" #include "chrome/browser/extensions/error_console/error_console.h" +#include "chrome/browser/extensions/error_console/error_console_test_observer.h" #include "chrome/browser/extensions/extension_action_runner.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" @@ -63,7 +64,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/search_test_utils.h" #include "chrome/test/base/ui_test_utils.h" @@ -6120,42 +6120,77 @@ will_register_listener.Reply("unused"); } -namespace { +// Tests behavior when a service worker is stopped while processing an event. +IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, + ServiceWorkerGoesAwayWhileHandlingRequest) { + ASSERT_TRUE(StartEmbeddedTestServer()); + static constexpr char kManifest[] = + R"({ + "name": "MV3 WebRequest", + "version": "0.1", + "manifest_version": 3, + "permissions": ["webRequest", "webRequestBlocking"], + "host_permissions": [ + "http://example.com/*" + ], + "background": {"service_worker": "background.js"} + })"; + // An extension with a listener that will spin forever on example.com + // requests. + static constexpr char kBackgroundJs[] = + R"(chrome.webRequest.onBeforeRequest.addListener( + (details) => { + if (details.url.includes('example.com')) { + chrome.test.sendMessage('received'); + // Spin FOREVER. + while (true) { } + } + return {}; + }, + {urls: ['<all_urls>'], types: ['main_frame']}, + ['blocking']); + chrome.test.sendMessage('ready');)"; -// A helper to wait for an error to be added for an extension. -// TODO(devlin): Pull this into a central test util file. -class ErrorObserver : public ErrorConsole::Observer { - public: - ErrorObserver(size_t errors_expected, ErrorConsole* error_console) - : errors_expected_(errors_expected), error_console_(error_console) { - observation_.Observe(error_console_.get()); - } + TestExtensionDir test_dir; + test_dir.WriteManifest(kManifest); + test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs); + const Extension* extension = LoadPolicyExtension(test_dir); + ASSERT_TRUE(extension); - // ErrorConsole::Observer implementation. - void OnErrorAdded(const ExtensionError* error) override { - ++errors_observed_; - if (errors_observed_ >= errors_expected_) { - run_loop_.Quit(); - } - } + // A single webRequest listener should be registered. + EXPECT_EQ(1u, web_request_router()->GetListenerCountForTesting( + profile(), "webRequest.onBeforeRequest")); - // Spin until the appropriate number of errors have been observed. - void WaitForErrors() { - if (errors_observed_ < errors_expected_) { - run_loop_.Run(); - } - } + // Navigate to example.com; the extension will receive the event and spin + // indefinitely. + // We navigate in a new tab to have a better signal of "request started". + // We can't wait for the request to finish, since the extension's listener + // never returns, which blocks the request. + const GURL url = + embedded_test_server()->GetURL("example.com", "/simple.html"); + content::TestNavigationObserver nav_observer(url); + nav_observer.StartWatchingNewWebContents(); + ExtensionTestMessageListener test_listener("received"); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(test_listener.WaitUntilSatisfied()); + // The web contents should still be loading, and should have no last + // committed URL since the extension is blocking the request. + EXPECT_TRUE(web_contents->IsLoading()); + EXPECT_EQ(GURL(), web_contents->GetLastCommittedURL()); - private: - size_t errors_expected_; - raw_ptr<ErrorConsole, DanglingUntriaged> error_console_; - size_t errors_observed_ = 0; - base::ScopedObservation<ErrorConsole, ErrorConsole::Observer> observation_{ - this}; - base::RunLoop run_loop_; -}; + // Stop the extension service worker. + browsertest_util::StopServiceWorkerForExtensionGlobalScope(profile(), + extension->id()); -} // namespace + // The request should be unblocked. + EXPECT_TRUE(content::WaitForLoadStop(web_contents)); + EXPECT_TRUE(nav_observer.last_navigation_succeeded()); + EXPECT_EQ(url, web_contents->GetLastCommittedURL()); +} // Tests that a MV3 extension that doesn't have the `webRequestAuthProvider` // permission cannot use blocking listeners for `onAuthRequired`. @@ -6184,11 +6219,9 @@ ['asyncBlocking']);)"; // Since we can't catch the error in the extension's JS, we instead listen to - // the error come into the error console. This also requires setting the user - // in developer mode. - ErrorConsole* error_console = ErrorConsole::Get(profile()); - profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); - ErrorObserver error_observer(1u, error_console); + // the error come into the error console. + ErrorConsoleTestObserver error_observer(1u, profile()); + error_observer.EnableErrorCollection(); // Load the extension and wait for the error to come. TestExtensionDir test_dir; @@ -6200,7 +6233,7 @@ error_observer.WaitForErrors(); const ErrorList& errors = - error_console->GetErrorsForExtension(extension->id()); + ErrorConsole::Get(profile())->GetErrorsForExtension(extension->id()); ASSERT_EQ(1u, errors.size()); EXPECT_TRUE( base::StartsWith(errors[0]->message(),
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc index 0f7a550..bef6d768 100644 --- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc +++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
@@ -116,7 +116,7 @@ } protected: - void AppendTabIdToRequestInfo(base::ListValue* params, int tab_id) { + void AppendTabIdToRequestInfo(base::Value::List* params, int tab_id) { base::Value::Dict request_info; request_info.Set("tabId", tab_id); params->Append(base::Value(std::move(request_info))); @@ -203,7 +203,7 @@ profile()->GetMediaDeviceIDSalt(), url::Origin::Create(origin), raw_device_id); - base::ListValue parameters; + base::Value::List parameters; parameters.Append(origin.spec()); parameters.Append(source_id_in_origin); std::string parameter_string;
diff --git a/chrome/browser/extensions/error_console/error_console_test_observer.cc b/chrome/browser/extensions/error_console/error_console_test_observer.cc new file mode 100644 index 0000000..06b51a4e9 --- /dev/null +++ b/chrome/browser/extensions/error_console/error_console_test_observer.cc
@@ -0,0 +1,40 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/error_console/error_console_test_observer.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" + +namespace extensions { + +ErrorConsoleTestObserver::ErrorConsoleTestObserver(size_t errors_expected, + Profile* profile) + : errors_expected_(errors_expected), profile_(profile) { + observation_.Observe(ErrorConsole::Get(profile_.get())); +} + +ErrorConsoleTestObserver::~ErrorConsoleTestObserver() = default; + +void ErrorConsoleTestObserver::EnableErrorCollection() { + // Errors are collected for extensions when the user preferences are set to + // enable developer mode. + profile_->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); +} + +void ErrorConsoleTestObserver::OnErrorAdded(const ExtensionError* error) { + ++errors_observed_; + if (errors_observed_ >= errors_expected_) { + run_loop_.Quit(); + } +} + +void ErrorConsoleTestObserver::WaitForErrors() { + if (errors_observed_ < errors_expected_) { + run_loop_.Run(); + } +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/error_console/error_console_test_observer.h b/chrome/browser/extensions/error_console/error_console_test_observer.h new file mode 100644 index 0000000..3943976 --- /dev/null +++ b/chrome/browser/extensions/error_console/error_console_test_observer.h
@@ -0,0 +1,43 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_ERROR_CONSOLE_ERROR_CONSOLE_TEST_OBSERVER_H_ +#define CHROME_BROWSER_EXTENSIONS_ERROR_CONSOLE_ERROR_CONSOLE_TEST_OBSERVER_H_ + +#include "base/memory/raw_ptr.h" +#include "base/run_loop.h" +#include "base/scoped_observation.h" +#include "chrome/browser/extensions/error_console/error_console.h" + +class Profile; + +namespace extensions { + +// A helper class to listen for extension errors being emitted in tests. +class ErrorConsoleTestObserver : public ErrorConsole::Observer { + public: + ErrorConsoleTestObserver(size_t errors_expected, Profile* profile); + ~ErrorConsoleTestObserver(); + + // Enables error collection for the associated profile. + void EnableErrorCollection(); + + // Waits until at least `errors_expected` errors have been seen. + void WaitForErrors(); + + private: + // ErrorConsole::Observer implementation. + void OnErrorAdded(const ExtensionError* error) override; + + size_t errors_expected_; + raw_ptr<Profile, DanglingUntriaged> profile_; + size_t errors_observed_ = 0; + base::ScopedObservation<ErrorConsole, ErrorConsole::Observer> observation_{ + this}; + base::RunLoop run_loop_; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_ERROR_CONSOLE_ERROR_CONSOLE_TEST_OBSERVER_H_
diff --git a/chrome/browser/extensions/permission_messages_unittest.cc b/chrome/browser/extensions/permission_messages_unittest.cc index 293beb1..3131793 100644 --- a/chrome/browser/extensions/permission_messages_unittest.cc +++ b/chrome/browser/extensions/permission_messages_unittest.cc
@@ -265,13 +265,14 @@ const char16_t kMessage[] = u"Access any PVR Mass Storage from HUMAX Co., Ltd. via USB"; - std::unique_ptr<base::ListValue> permission_list(new base::ListValue()); - permission_list->Append(base::Value::FromUniquePtrValue( + base::Value::List permission_list; + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ad, 0x138c, -1, -1).ToValue())); + base::Value permission_value = base::Value(std::move(permission_list)); UsbDevicePermission permission( PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice)); - ASSERT_TRUE(permission.FromValue(permission_list.get(), nullptr, nullptr)); + ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr)); PermissionMessages messages = GetMessages(permission.GetPermissions()); ASSERT_EQ(1U, messages.size()); @@ -280,13 +281,14 @@ { const char16_t kMessage[] = u"Access USB devices from HUMAX Co., Ltd."; - std::unique_ptr<base::ListValue> permission_list(new base::ListValue()); - permission_list->Append(base::Value::FromUniquePtrValue( + base::Value::List permission_list; + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ad, 0x138d, -1, -1).ToValue())); + base::Value permission_value = base::Value(std::move(permission_list)); UsbDevicePermission permission( PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice)); - ASSERT_TRUE(permission.FromValue(permission_list.get(), nullptr, nullptr)); + ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr)); PermissionMessages messages = GetMessages(permission.GetPermissions()); ASSERT_EQ(1U, messages.size()); @@ -295,13 +297,14 @@ { const char16_t kMessage[] = u"Access USB devices from an unknown vendor"; - std::unique_ptr<base::ListValue> permission_list(new base::ListValue()); - permission_list->Append(base::Value::FromUniquePtrValue( + base::Value::List permission_list; + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ae, 0x138d, -1, -1).ToValue())); + base::Value permission_value = base::Value(std::move(permission_list)); UsbDevicePermission permission( PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice)); - ASSERT_TRUE(permission.FromValue(permission_list.get(), nullptr, nullptr)); + ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr)); PermissionMessages messages = GetMessages(permission.GetPermissions()); ASSERT_EQ(1U, messages.size()); @@ -318,25 +321,27 @@ }; // Prepare data set - std::unique_ptr<base::ListValue> permission_list(new base::ListValue()); - permission_list->Append(base::Value::FromUniquePtrValue( + base::Value::List permission_list; + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ad, 0x138c, -1, -1).ToValue())); // This device's product ID is not in Chrome's database. - permission_list->Append(base::Value::FromUniquePtrValue( + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ad, 0x138d, -1, -1).ToValue())); // This additional unknown product will be collapsed into the entry above. - permission_list->Append(base::Value::FromUniquePtrValue( + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ad, 0x138e, -1, -1).ToValue())); // This device's vendor ID is not in Chrome's database. - permission_list->Append(base::Value::FromUniquePtrValue( + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02ae, 0x138d, -1, -1).ToValue())); // This additional unknown vendor will be collapsed into the entry above. - permission_list->Append(base::Value::FromUniquePtrValue( + permission_list.Append(base::Value::FromUniquePtrValue( UsbDevicePermissionData(0x02af, 0x138d, -1, -1).ToValue())); + base::Value permission_value = base::Value(std::move(permission_list)); + UsbDevicePermission permission( PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice)); - ASSERT_TRUE(permission.FromValue(permission_list.get(), nullptr, nullptr)); + ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr)); PermissionMessages messages = GetMessages(permission.GetPermissions()); ASSERT_EQ(1U, messages.size());
diff --git a/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc b/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc index d24778e..dd9098d3d 100644 --- a/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc +++ b/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc
@@ -61,8 +61,8 @@ // |optional_permissions|. scoped_refptr<const Extension> CreateExtensionWithPermission( mojom::ManifestLocation location, - const base::ListValue* required_permissions, - const base::ListValue* optional_permissions) { + const base::Value::List* required_permissions, + const base::Value::List* optional_permissions) { base::Value::Dict manifest_dict; manifest_dict.Set(manifest_keys::kName, "test"); manifest_dict.Set(manifest_keys::kVersion, "0.1"); @@ -95,11 +95,11 @@ // Verifies that extensions with conflicting permissions cannot be loaded. TEST_F(PermissionsBasedManagementPolicyProviderTest, APIPermissions) { // Prepares the extension manifest. - base::ListValue required_permissions; + base::Value::List required_permissions; required_permissions.Append( GetAPIPermissionName(APIPermissionID::kDownloads)); required_permissions.Append(GetAPIPermissionName(APIPermissionID::kCookie)); - base::ListValue optional_permissions; + base::Value::List optional_permissions; optional_permissions.Append(GetAPIPermissionName(APIPermissionID::kProxy)); scoped_refptr<const Extension> extension = CreateExtensionWithPermission(
diff --git a/chrome/browser/extensions/policy_handlers_unittest.cc b/chrome/browser/extensions/policy_handlers_unittest.cc index b1e1bbc8..2955b1b 100644 --- a/chrome/browser/extensions/policy_handlers_unittest.cc +++ b/chrome/browser/extensions/policy_handlers_unittest.cc
@@ -105,7 +105,7 @@ base::JSON_PARSE_CHROMIUM_EXTENSIONS | base::JSON_ALLOW_TRAILING_COMMAS; TEST(ExtensionListPolicyHandlerTest, CheckPolicySettings) { - base::ListValue list; + base::Value::List list; policy::PolicyMap policy_map; policy::PolicyErrorMap errors; ExtensionListPolicyHandler handler(policy::key::kExtensionInstallBlocklist, @@ -113,7 +113,8 @@ policy_map.Set(policy::key::kExtensionInstallBlocklist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -121,7 +122,8 @@ list.Append("abcdefghijklmnopabcdefghijklmnop"); policy_map.Set(policy::key::kExtensionInstallBlocklist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -129,7 +131,8 @@ list.Append("*"); policy_map.Set(policy::key::kExtensionInstallBlocklist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -137,7 +140,8 @@ list.Append("invalid"); policy_map.Set(policy::key::kExtensionInstallBlocklist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_FALSE(errors.empty()); @@ -190,8 +194,8 @@ } TEST(ExtensionListPolicyHandlerTest, ApplyPolicySettings) { - base::ListValue policy; - base::ListValue expected; + base::Value::List policy; + base::Value::List expected; policy::PolicyMap policy_map; PrefValueMap prefs; base::Value* value = nullptr; @@ -203,22 +207,24 @@ policy_map.Set(policy::key::kExtensionInstallBlocklist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, policy.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(policy.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); EXPECT_TRUE(prefs.GetValue(kTestPref, &value)); - EXPECT_EQ(expected, *value); + EXPECT_EQ(expected, value->GetList()); policy.Append("invalid"); policy_map.Set(policy::key::kExtensionInstallBlocklist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, policy.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(policy.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); EXPECT_TRUE(prefs.GetValue(kTestPref, &value)); - EXPECT_EQ(expected, *value); + EXPECT_EQ(expected, value->GetList()); } TEST(ExtensionInstallForceListPolicyHandlerTest, CheckPolicySettings) { - base::ListValue list; + base::Value::List list; policy::PolicyMap policy_map; policy::PolicyErrorMap errors; ExtensionInstallForceListPolicyHandler handler; @@ -226,7 +232,8 @@ // Start with an empty policy. policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -235,7 +242,8 @@ list.Append("abcdefghijklmnopabcdefghijklmnop;http://example.com"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -245,7 +253,8 @@ list.Append("adfasdf;http://example.com"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_EQ(1U, errors.size()); @@ -254,7 +263,8 @@ list.Append("abcdefghijklmnopabcdefghijklmnop;nourl"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_EQ(2U, errors.size()); @@ -263,14 +273,15 @@ list.Append("abcdefghijklmnopabcdefghijklmnop"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_EQ(2U, errors.size()); } TEST(ExtensionInstallForceListPolicyHandlerTest, ApplyPolicySettings) { - base::ListValue policy; + base::Value::List policy; base::Value::Dict expected; policy::PolicyMap policy_map; PrefValueMap prefs; @@ -286,7 +297,8 @@ // Set the policy to an empty value. This shouldn't affect the pref. policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, policy.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(policy.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); EXPECT_TRUE(prefs.GetValue(pref_names::kInstallForceList, &value)); EXPECT_EQ(expected, *value); @@ -299,7 +311,8 @@ expected, "abcdefghijklmnopabcdefghijklmnop", "http://example.com"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, policy.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(policy.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); EXPECT_TRUE(prefs.GetValue(pref_names::kInstallForceList, &value)); EXPECT_EQ(expected, *value); @@ -316,7 +329,8 @@ "https://clients2.google.com/service/update2/crx"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, policy.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(policy.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); EXPECT_TRUE(prefs.GetValue(pref_names::kInstallForceList, &value)); EXPECT_EQ(expected, *value); @@ -326,7 +340,8 @@ policy.Append("invalid"); policy_map.Set(policy::key::kExtensionInstallForcelist, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, policy.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(policy.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); EXPECT_TRUE(prefs.GetValue(pref_names::kInstallForceList, &value)); EXPECT_EQ(expected, *value); @@ -334,7 +349,7 @@ } TEST(ExtensionURLPatternListPolicyHandlerTest, CheckPolicySettings) { - base::ListValue list; + base::Value::List list; policy::PolicyMap policy_map; policy::PolicyErrorMap errors; ExtensionURLPatternListPolicyHandler handler( @@ -342,7 +357,8 @@ policy_map.Set(policy::key::kExtensionInstallSources, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -350,7 +366,8 @@ list.Append("http://*.google.com/*"); policy_map.Set(policy::key::kExtensionInstallSources, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -358,7 +375,8 @@ list.Append("<all_urls>"); policy_map.Set(policy::key::kExtensionInstallSources, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.empty()); @@ -366,7 +384,8 @@ list.Append("invalid"); policy_map.Set(policy::key::kExtensionInstallSources, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_FALSE(errors.empty()); @@ -378,7 +397,8 @@ list.Append("*"); policy_map.Set(policy::key::kExtensionInstallSources, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); errors.Clear(); EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_FALSE(errors.empty()); @@ -387,7 +407,7 @@ } TEST(ExtensionURLPatternListPolicyHandlerTest, ApplyPolicySettings) { - base::ListValue list; + base::Value::List list; policy::PolicyMap policy_map; PrefValueMap prefs; base::Value* value = nullptr; @@ -397,7 +417,8 @@ list.Append("https://corp.monkey.net/*"); policy_map.Set(policy::key::kExtensionInstallSources, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, list.Clone(), nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(list.Clone()), + nullptr); handler.ApplyPolicySettings(policy_map, &prefs); ASSERT_TRUE(prefs.GetValue(kTestPref, &value)); EXPECT_EQ(list, *value);
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index a505835..9e326f8 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/error_console/error_console.h" +#include "chrome/browser/extensions/error_console/error_console_test_observer.h" #include "chrome/browser/extensions/extension_action_runner.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" @@ -40,7 +41,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/api/web_navigation.h" -#include "chrome/common/pref_names.h" #include "chrome/test/base/ui_test_utils.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/gcm_driver/fake_gcm_profile_service.h" @@ -138,39 +138,6 @@ } // namespace -class ErrorObserver : public ErrorConsole::Observer { - public: - ErrorObserver(size_t errors_expected, ErrorConsole* error_console) - : errors_expected_(errors_expected), - error_console_(error_console), - errors_observed_(0) { - observation_.Observe(error_console_.get()); - } - - // ErrorConsole::Observer implementation. - void OnErrorAdded(const ExtensionError* error) override { - ++errors_observed_; - if (errors_observed_ >= errors_expected_) { - run_loop_.Quit(); - } - } - - // Spin until the appropriate number of errors have been observed. - void WaitForErrors() { - if (errors_observed_ < errors_expected_) { - run_loop_.Run(); - } - } - - private: - size_t errors_expected_; - raw_ptr<ErrorConsole> error_console_; - size_t errors_observed_; - base::ScopedObservation<ErrorConsole, ErrorConsole::Observer> observation_{ - this}; - base::RunLoop run_loop_; -}; - class ServiceWorkerTest : public ExtensionApiTest { public: ServiceWorkerTest(const ServiceWorkerTest&) = delete; @@ -422,10 +389,9 @@ // Tests that registering a module service worker with dynamic import fails. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, ModuleServiceWorkerWithDynamicImport) { - ErrorConsole* error_console = ErrorConsole::Get(profile()); - profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); constexpr size_t kErrorsExpected = 1u; - ErrorObserver observer(kErrorsExpected, error_console); + ErrorConsoleTestObserver observer(kErrorsExpected, profile()); + observer.EnableErrorCollection(); const Extension* extension = LoadExtension( test_data_dir_.AppendASCII("service_worker/worker_based_background/" @@ -433,7 +399,7 @@ observer.WaitForErrors(); const ErrorList& error_list = - error_console->GetErrorsForExtension(extension->id()); + ErrorConsole::Get(profile())->GetErrorsForExtension(extension->id()); ASSERT_EQ(kErrorsExpected, error_list.size()); ASSERT_EQ( error_list[0]->message(), @@ -446,12 +412,9 @@ // synchronously throwing a runtime error. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, ServiceWorkerWithRegistrationFailure) { - // The error console only captures errors if the user is in dev mode. - profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); - constexpr size_t kErrorsExpected = 2u; - ErrorConsole* error_console = ErrorConsole::Get(profile()); - ErrorObserver observer(kErrorsExpected, error_console); + ErrorConsoleTestObserver observer(kErrorsExpected, profile()); + observer.EnableErrorCollection(); const Extension* extension = LoadExtension( test_data_dir_.AppendASCII("service_worker/worker_based_background/" @@ -461,7 +424,7 @@ ASSERT_TRUE(extension); observer.WaitForErrors(); const ErrorList& error_list = - error_console->GetErrorsForExtension(extension->id()); + ErrorConsole::Get(profile())->GetErrorsForExtension(extension->id()); ASSERT_EQ(kErrorsExpected, error_list.size()); std::vector<std::u16string> error_message_list; @@ -478,11 +441,9 @@ // Tests that an error is generated if there is a syntax error in the service // worker script. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, SyntaxError) { - ErrorConsole* error_console = ErrorConsole::Get(profile()); - // Error is observed on extension UI for developer mode only. - profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); const size_t kErrorsExpected = 1u; - ErrorObserver observer(kErrorsExpected, error_console); + ErrorConsoleTestObserver observer(kErrorsExpected, profile()); + observer.EnableErrorCollection(); ExtensionTestMessageListener test_listener("ready", ReplyBehavior::kWillReply); @@ -495,7 +456,7 @@ observer.WaitForErrors(); const ErrorList& error_list = - error_console->GetErrorsForExtension(extension->id()); + ErrorConsole::Get(profile())->GetErrorsForExtension(extension->id()); ASSERT_EQ(kErrorsExpected, error_list.size()); EXPECT_EQ(ExtensionError::RUNTIME_ERROR, error_list[0]->type()); EXPECT_THAT(base::UTF16ToUTF8(error_list[0]->message()), @@ -506,11 +467,9 @@ // Tests that an error is generated if there is an undefined variable in the // service worker script. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, UndefinedVariable) { - ErrorConsole* error_console = ErrorConsole::Get(profile()); - // Error is observed on extension UI for developer mode only. - profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); const size_t kErrorsExpected = 1u; - ErrorObserver observer(kErrorsExpected, error_console); + ErrorConsoleTestObserver observer(kErrorsExpected, profile()); + observer.EnableErrorCollection(); ExtensionTestMessageListener test_listener("ready", ReplyBehavior::kWillReply); @@ -523,7 +482,7 @@ observer.WaitForErrors(); const ErrorList& error_list = - error_console->GetErrorsForExtension(extension->id()); + ErrorConsole::Get(profile())->GetErrorsForExtension(extension->id()); ASSERT_EQ(kErrorsExpected, error_list.size()); EXPECT_EQ(ExtensionError::RUNTIME_ERROR, error_list[0]->type()); EXPECT_THAT(base::UTF16ToUTF8(error_list[0]->message()), @@ -534,19 +493,18 @@ // Tests that an error is generated if console.error() is called from an // extension's service worker. IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, ConsoleError) { - ErrorConsole* error_console = ErrorConsole::Get(profile()); - // Error is observed on extension UI for developer mode only. - profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true); const size_t kErrorsExpected = 1u; - ErrorObserver observer(kErrorsExpected, error_console); + ErrorConsoleTestObserver observer(kErrorsExpected, profile()); + observer.EnableErrorCollection(); ASSERT_TRUE( RunExtensionTest("service_worker/worker_based_background/console_error")) << message_; observer.WaitForErrors(); - const ErrorList& error_list = error_console->GetErrorsForExtension( - ExtensionBrowserTest::last_loaded_extension_id()); + const ErrorList& error_list = + ErrorConsole::Get(profile())->GetErrorsForExtension( + ExtensionBrowserTest::last_loaded_extension_id()); ASSERT_EQ(kErrorsExpected, error_list.size()); EXPECT_EQ(ExtensionError::RUNTIME_ERROR, error_list[0]->type()); EXPECT_THAT(base::UTF16ToUTF8(error_list[0]->message()),
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedServiceBridge.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedServiceBridge.java index c511455..fc3dcad 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedServiceBridge.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedServiceBridge.java
@@ -5,11 +5,8 @@ package org.chromium.chrome.browser.feed; import android.content.Context; -import android.os.Build; import android.util.DisplayMetrics; -import androidx.annotation.RequiresApi; - import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -89,11 +86,8 @@ } /** Returns the top user specified locale. */ - @RequiresApi(Build.VERSION_CODES.N) private static Locale getLocale(Context context) { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? context.getResources().getConfiguration().getLocales().get(0) - : context.getResources().getConfiguration().locale; + return context.getResources().getConfiguration().getLocales().get(0); } // Java functionality needed for the native FeedService.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 937095c..c741605c 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -5007,6 +5007,11 @@ "expiry_milestone": 115 }, { + "name": "omnibox-grouping-framework", + "owners": ["manukh", "mahmadi", "ender", "chrome-desktop-search@google.com" ], + "expiry_milestone": 120 + }, + { "name": "omnibox-history-quick-provider-specificity-score-count-unique-hosts", "owners": [ "manukh", "chrome-omnibox-team@google.com" ], "expiry_milestone": 120 @@ -5801,11 +5806,6 @@ "expiry_milestone": 114 }, { - "name": "reduce-display-notifications", - "owners": [ "baileyberro", "zentaro" ], - "expiry_milestone": 112 - }, - { "name": "reduce-horizontal-fling-velocity", "owners": [ "flackr", "input-dev" ], "expiry_milestone": 95
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 972f87fb..e522d9a 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1998,6 +1998,11 @@ const char kOmniboxFuzzyUrlSuggestionsDescription[] = "Enables URL suggestions for inputs that may contain typos."; +const char kOmniboxGroupingFrameworkName[] = "Omnibox Grouping Framework"; +const char kOmniboxGroupingFrameworkDescription[] = + "Enables an alternative grouping implementation for omnibox " + "autocompletion."; + const char kOmniboxHistoryQuickProviderSpecificityScoreCountUniqueHostsName[] = "Omnibox HQP Specificity"; const char
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index b5481b28..69151e6 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1127,6 +1127,9 @@ extern const char kOmniboxFuzzyUrlSuggestionsName[]; extern const char kOmniboxFuzzyUrlSuggestionsDescription[]; +extern const char kOmniboxGroupingFrameworkName[]; +extern const char kOmniboxGroupingFrameworkDescription[]; + extern const char kOmniboxHistoryQuickProviderSpecificityScoreCountUniqueHostsName[]; extern const char
diff --git a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java index 6e393ce..ca2de33e 100644 --- a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java +++ b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptor.java
@@ -163,9 +163,8 @@ // This flag ensures the broadcast is delivered with foreground priority to speed up the // broadcast delivery. - if (shouldUseBroadcast && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - } + if (shouldUseBroadcast) intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + // Use request code to distinguish different PendingIntents on Android. int originalRequestCode = pendingIntentProvider != null ? pendingIntentProvider.getRequestCode() : 0;
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 15805f8c..a98d28d 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -306,12 +306,12 @@ ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdPageLoadCustomSampling2::kEntryName); + ukm::builders::AdPageLoadCustomSampling3::kEntryName); EXPECT_EQ(1u, entries.size()); const int64_t* reported_average_viewport_density = ukm_recorder.GetEntryMetric(entries.front(), - ukm::builders::AdPageLoadCustomSampling2:: + ukm::builders::AdPageLoadCustomSampling3:: kAverageViewportAdDensityName); EXPECT_TRUE(reported_average_viewport_density); @@ -323,6 +323,59 @@ expected_final_viewport_density); } +IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, + AverageViewportAdDensity_ImageAd) { + SetRulesetWithRules( + {subresource_filter::testing::CreateSuffixRule("pixel.png")}); + + ukm::TestAutoSetUkmRecorder ukm_recorder; + + auto waiter = CreatePageLoadMetricsTestWaiter(); + + GURL url = embedded_test_server()->GetURL( + "a.com", "/ads_observer/blank_with_adiframe_writer.html"); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + waiter->SetMainFrameImageAdRectsExpectation(); + + GURL image_url = + embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png"); + + std::string create_image_script = content::JsReplace(R"( + const img = document.createElement('img'); + img.style.position = 'fixed'; + img.style.left = 0; + img.style.top = 0; + img.width = 5; + img.height = 5; + img.src = $1; + document.body.appendChild(img);)", + image_url.spec()); + + EXPECT_TRUE(ExecJs(web_contents, create_image_script)); + + waiter->Wait(); + + EXPECT_TRUE(waiter->DidObserveMainFrameImageAdRect(gfx::Rect(0, 0, 5, 5))); + + ASSERT_TRUE( + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); + + auto entries = ukm_recorder.GetEntriesByName( + ukm::builders::AdPageLoadCustomSampling3::kEntryName); + EXPECT_EQ(1u, entries.size()); + + const int64_t* reported_average_viewport_density = + ukm_recorder.GetEntryMetric(entries.front(), + ukm::builders::AdPageLoadCustomSampling3:: + kAverageViewportAdDensityName); + + EXPECT_TRUE(reported_average_viewport_density); +} + // Verifies that the page ad density records the maximum value during // a page's lifecycling by creating a large ad frame, destroying it, and // creating a smaller iframe. The ad density recorded is the density with
diff --git a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditControllerTest.java b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditControllerTest.java index 8305c70b..99d94abed 100644 --- a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditControllerTest.java +++ b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditControllerTest.java
@@ -40,7 +40,6 @@ import android.content.ClipboardManager; import android.content.Context; import android.content.res.Resources; -import android.os.Build; import android.os.PersistableBundle; import androidx.test.core.app.ApplicationProvider; @@ -92,10 +91,8 @@ PropertyModel mModel; private void verifyTheClipdataContainSensitiveExtra(ClipData clipData) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - PersistableBundle extras = clipData.getDescription().getExtras(); - assertTrue(extras.getBoolean("android.content.extra.IS_SENSITIVE")); - } + PersistableBundle extras = clipData.getDescription().getExtras(); + assertTrue(extras.getBoolean("android.content.extra.IS_SENSITIVE")); } @Before
diff --git a/chrome/browser/printing/print_backend_service_manager.cc b/chrome/browser/printing/print_backend_service_manager.cc index 2fa2bf9..761aad3 100644 --- a/chrome/browser/printing/print_backend_service_manager.cc +++ b/chrome/browser/printing/print_backend_service_manager.cc
@@ -56,7 +56,7 @@ size_t GetClientsCountForRemoteId( const PrintBackendServiceManager::PrintClientsMap& clients, - const std::string& remote_id) { + const PrintBackendServiceManager::RemoteId& remote_id) { auto iter = clients.find(remote_id); if (iter != clients.end()) { DCHECK(!iter->second.empty()); @@ -75,6 +75,13 @@ } // namespace +PrintBackendServiceManager::CallbackContext::CallbackContext() = default; + +PrintBackendServiceManager::CallbackContext::CallbackContext( + PrintBackendServiceManager::CallbackContext&& other) noexcept = default; + +PrintBackendServiceManager::CallbackContext::~CallbackContext() = default; + PrintBackendServiceManager::PrintBackendServiceManager() = default; PrintBackendServiceManager::~PrintBackendServiceManager() = default; @@ -126,7 +133,7 @@ void PrintBackendServiceManager::UnregisterClient(uint32_t id) { // Determine which client type has this ID, and remove it once found. absl::optional<ClientType> client_type; - std::string remote_id = GetRemoteIdForPrinterName(kEmptyPrinterName); + RemoteId remote_id = GetRemoteIdForPrinterName(kEmptyPrinterName); if (query_clients_.erase(id) != 0) { client_type = ClientType::kQuery; } else if (query_with_ui_clients_.erase(id) != 0) { @@ -178,7 +185,7 @@ LogCallToRemote("EnumeratePrinters", context); service->EnumeratePrinters( base::BindOnce(&PrintBackendServiceManager::OnDidEnumeratePrinters, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::FetchCapabilities( @@ -198,7 +205,7 @@ service->FetchCapabilities( printer_name, base::BindOnce(&PrintBackendServiceManager::OnDidFetchCapabilities, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::GetDefaultPrinterName( @@ -214,7 +221,7 @@ LogCallToRemote("GetDefaultPrinterName", context); service->GetDefaultPrinterName( base::BindOnce(&PrintBackendServiceManager::OnDidGetDefaultPrinterName, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::GetPrinterSemanticCapsAndDefaults( @@ -237,7 +244,7 @@ printer_name, base::BindOnce( &PrintBackendServiceManager::OnDidGetPrinterSemanticCapsAndDefaults, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::UseDefaultSettings( @@ -261,7 +268,7 @@ LogCallToRemote("UseDefaultSettings", context); service->UseDefaultSettings( base::BindOnce(&PrintBackendServiceManager::OnDidUseDefaultSettings, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } #if BUILDFLAG(IS_WIN) @@ -286,7 +293,7 @@ service->AskUserForSettings( NativeViewToUint(parent_view), max_pages, has_selection, is_scripted, base::BindOnce(&PrintBackendServiceManager::OnDidAskUserForSettings, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } #endif // BUILDFLAG(IS_WIN) @@ -308,7 +315,7 @@ service->UpdatePrintSettings( std::move(job_settings), base::BindOnce(&PrintBackendServiceManager::OnDidUpdatePrintSettings, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::StartPrinting( @@ -332,7 +339,7 @@ service->StartPrinting( document_cookie, document_name, target_type, settings, base::BindOnce(&PrintBackendServiceManager::OnDidStartPrinting, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } #if BUILDFLAG(IS_WIN) @@ -362,7 +369,7 @@ std::move(serialized_page_data), page.page_size(), page.page_content_rect(), page.shrink_factor(), base::BindOnce(&PrintBackendServiceManager::OnDidRenderPrintedPage, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } #endif // BUILDFLAG(IS_WIN) @@ -387,7 +394,7 @@ service->RenderPrintedDocument( document_cookie, page_count, data_type, std::move(serialized_data), base::BindOnce(&PrintBackendServiceManager::OnDidRenderPrintedDocument, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::DocumentDone( @@ -408,7 +415,7 @@ service->DocumentDone( document_cookie, base::BindOnce(&PrintBackendServiceManager::OnDidDocumentDone, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } void PrintBackendServiceManager::Cancel( @@ -428,7 +435,7 @@ LogCallToRemote("Cancel", context); service->Cancel(document_cookie, base::BindOnce(&PrintBackendServiceManager::OnDidCancel, - base::Unretained(this), context)); + base::Unretained(this), std::move(context))); } bool PrintBackendServiceManager::PrinterDriverFoundToRequireElevatedPrivilege( @@ -455,7 +462,8 @@ sandboxed_service_remote_for_test_ = remote; sandboxed_service_remote_for_test_->set_disconnect_handler(base::BindOnce( &PrintBackendServiceManager::OnRemoteDisconnected, base::Unretained(this), - /*sandboxed=*/true, /*remote_id=*/std::string())); + /*sandboxed=*/true, + GetRemoteIdForPrinterName(/*printer_name=*/std::string()))); } void PrintBackendServiceManager::SetServiceForFallbackTesting( @@ -463,7 +471,8 @@ unsandboxed_service_remote_for_test_ = remote; unsandboxed_service_remote_for_test_->set_disconnect_handler(base::BindOnce( &PrintBackendServiceManager::OnRemoteDisconnected, base::Unretained(this), - /*sandboxed=*/false, /*remote_id=*/std::string())); + /*sandboxed=*/false, + GetRemoteIdForPrinterName(/*printer_name=*/std::string()))); } // static @@ -483,28 +492,38 @@ } } -std::string PrintBackendServiceManager::GetRemoteIdForPrinterName( - const std::string& printer_name) const { - if (sandboxed_service_remote_for_test_) { - // Test environment is always just one instance for all printers. - return std::string(); - } - +PrintBackendServiceManager::RemoteId +PrintBackendServiceManager::GetRemoteIdForPrinterName( + const std::string& printer_name) { #if BUILDFLAG(IS_WIN) - // Windows drivers are not thread safe. Use a process per driver to prevent - // bad interactions when interfacing to multiple drivers in parallel. - // https://crbug.com/957242 - return printer_name; -#else - return std::string(); + if (!sandboxed_service_remote_for_test_) { + // Windows drivers are not thread safe. Use a process per driver to prevent + // bad interactions when interfacing to multiple drivers in parallel. + // https://crbug.com/957242 + auto iter = remote_id_map_.find(printer_name); + if (iter != remote_id_map_.end()) { + return iter->second; + } + + // No remote yet for this printer so make one. RemoteId is only used within + // browse process management code, so a simple incrementing sequence is + // sufficient. + static uint32_t id_sequence = 0; + return remote_id_map_.insert({printer_name, RemoteId(++id_sequence)}) + .first->second; + } #endif + + // Non-Windows platforms and the testing environment always just use one + // instance for all printers. + return RemoteId(1); } absl::optional<uint32_t> PrintBackendServiceManager::RegisterClient( ClientType client_type, const std::string& printer_name) { uint32_t client_id = ++last_client_id_; - std::string remote_id = GetRemoteIdForPrinterName(printer_name); + RemoteId remote_id = GetRemoteIdForPrinterName(printer_name); VLOG(1) << "Registering a client with ID " << client_id << " for print backend service."; @@ -627,7 +646,7 @@ } } - std::string remote_id = GetRemoteIdForPrinterName(printer_name); + RemoteId remote_id = GetRemoteIdForPrinterName(printer_name); if (should_sandbox) { return GetServiceFromBundle(remote_id, client_type, /*sandboxed=*/true, sandboxed_remotes_bundles_); @@ -639,7 +658,7 @@ template <class T> mojo::Remote<mojom::PrintBackendService>& PrintBackendServiceManager::GetServiceFromBundle( - const std::string& remote_id, + const RemoteId& remote_id, ClientType client_type, bool sandboxed, RemotesBundleMap<T>& bundle_map) { @@ -732,7 +751,7 @@ absl::optional<base::TimeDelta> PrintBackendServiceManager::DetermineIdleTimeoutUpdateOnRegisteredClient( ClientType registered_client_type, - const std::string& remote_id) const { + const RemoteId& remote_id) const { switch (registered_client_type) { case ClientType::kQuery: DCHECK(!query_clients_.empty()); @@ -790,7 +809,7 @@ absl::optional<base::TimeDelta> PrintBackendServiceManager::DetermineIdleTimeoutUpdateOnUnregisteredClient( ClientType unregistered_client_type, - const std::string& remote_id) const { + const RemoteId& remote_id) const { switch (unregistered_client_type) { case ClientType::kQuery: // Other query types have longer timeouts, so no need to update if @@ -847,7 +866,7 @@ void PrintBackendServiceManager::SetServiceIdleHandler( mojo::Remote<printing::mojom::PrintBackendService>& service, bool sandboxed, - const std::string& remote_id, + const RemoteId& remote_id, const base::TimeDelta& timeout) { DVLOG(1) << "Updating idle timeout for " << (sandboxed ? "sandboxed" : "unsandboxed") @@ -864,7 +883,7 @@ } void PrintBackendServiceManager::UpdateServiceIdleTimeoutByRemoteId( - const std::string& remote_id, + const RemoteId& remote_id, const base::TimeDelta& timeout) { auto sandboxed_iter = sandboxed_remotes_bundles_.find(remote_id); if (sandboxed_iter != sandboxed_remotes_bundles_.end()) { @@ -883,7 +902,7 @@ } void PrintBackendServiceManager::OnIdleTimeout(bool sandboxed, - const std::string& remote_id) { + const RemoteId& remote_id) { DVLOG(1) << "Print Backend service idle timeout for " << (sandboxed ? "sandboxed" : "unsandboxed") << " remote id `" << remote_id << "`"; @@ -896,7 +915,7 @@ void PrintBackendServiceManager::OnRemoteDisconnected( bool sandboxed, - const std::string& remote_id) { + const RemoteId& remote_id) { DVLOG(1) << "Print Backend service disconnected for " << (sandboxed ? "sandboxed" : "unsandboxed") << " remote id `" << remote_id << "`"; @@ -1048,7 +1067,7 @@ template <class... T, class... X> void PrintBackendServiceManager::SaveCallback( RemoteSavedCallbacks<T...>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, const base::UnguessableToken& saved_callback_id, base::OnceCallback<void(X...)> callback) { saved_callbacks[remote_id].emplace(saved_callback_id, std::move(callback)); @@ -1057,7 +1076,7 @@ template <class... T, class... X> void PrintBackendServiceManager::ServiceCallbackDone( RemoteSavedCallbacks<T...>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, const base::UnguessableToken& saved_callback_id, X... data) { auto found_callback_map = saved_callbacks.find(remote_id); @@ -1187,7 +1206,7 @@ template <class T> void PrintBackendServiceManager::RunSavedCallbacksStructResult( RemoteSavedStructCallbacks<T>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, mojo::StructPtr<T> result_to_clone) { auto found_callbacks_map = saved_callbacks.find(remote_id); if (found_callbacks_map == saved_callbacks.end()) @@ -1213,7 +1232,7 @@ template <class... T> void PrintBackendServiceManager::RunSavedCallbacks( RemoteSavedCallbacks<T...>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, T... result) { auto found_callbacks_map = saved_callbacks.find(remote_id); if (found_callbacks_map == saved_callbacks.end())
diff --git a/chrome/browser/printing/print_backend_service_manager.h b/chrome/browser/printing/print_backend_service_manager.h index 9371c475..e03ab472 100644 --- a/chrome/browser/printing/print_backend_service_manager.h +++ b/chrome/browser/printing/print_backend_service_manager.h
@@ -12,6 +12,7 @@ #include "base/containers/flat_set.h" #include "base/memory/raw_ptr.h" #include "base/no_destructor.h" +#include "base/types/strong_alias.h" #include "base/unguessable_token.h" #include "base/values.h" #include "build/build_config.h" @@ -43,8 +44,13 @@ class PrintBackendServiceManager { public: + using RemoteId = base::StrongAlias<class RemoteIdTag, uint32_t>; + + // Contains set of client IDs. using ClientsSet = base::flat_set<uint32_t>; - using PrintClientsMap = base::flat_map<std::string, ClientsSet>; + + // Mapping of clients to each remote ID that is for printing. + using PrintClientsMap = base::flat_map<RemoteId, ClientsSet>; // Amount of idle time to wait before resetting the connection to the service. static constexpr base::TimeDelta kNoClientsRegisteredResetOnIdleTimeout = @@ -201,8 +207,7 @@ // Key is the remote ID that enables finding the correct remote. Note that // the remote ID does not necessarily mean the printer name. template <class... T> - using RemoteSavedCallbacks = - base::flat_map<std::string, SavedCallbacks<T...>>; + using RemoteSavedCallbacks = base::flat_map<RemoteId, SavedCallbacks<T...>>; template <class... T> using RemoteSavedStructCallbacks = RemoteSavedCallbacks<mojo::StructPtr<T...>>; @@ -247,14 +252,18 @@ template <class T> using RemotesBundleMap = - base::flat_map<std::string, std::unique_ptr<RemotesBundle<T>>>; + base::flat_map<RemoteId, std::unique_ptr<RemotesBundle<T>>>; // PrintBackendServiceManager needs to be able to run a callback either after // a successful return from the service or after the remote was disconnected. // This structure is used to save the callback's context. struct CallbackContext { + CallbackContext(); + CallbackContext(CallbackContext&& other) noexcept; + ~CallbackContext(); + bool is_sandboxed; - std::string remote_id; + RemoteId remote_id; base::UnguessableToken saved_callback_id; }; @@ -269,7 +278,7 @@ void SetCrashKeys(const std::string& printer_name); // Determine the remote ID that is used for the specified `printer_name`. - std::string GetRemoteIdForPrinterName(const std::string& printer_name) const; + RemoteId GetRemoteIdForPrinterName(const std::string& printer_name); // Common helper for registering clients. absl::optional<uint32_t> RegisterClient(ClientType client_type, @@ -299,7 +308,7 @@ // Helper to `GetService` for a particular remotes bundle type. template <class T> mojo::Remote<mojom::PrintBackendService>& GetServiceFromBundle( - const std::string& remote_id, + const RemoteId& remote_id, ClientType client_type, bool sandboxed, RemotesBundleMap<T>& bundle_map); @@ -312,33 +321,33 @@ // a new client registered for `registered_client_type`. absl::optional<base::TimeDelta> DetermineIdleTimeoutUpdateOnRegisteredClient( ClientType registered_client_type, - const std::string& remote_id) const; + const RemoteId& remote_id) const; // Determine if idle timeout should be modified after a client of type // `unregistered_client_type` has been unregistered. absl::optional<base::TimeDelta> DetermineIdleTimeoutUpdateOnUnregisteredClient( ClientType unregistered_client_type, - const std::string& remote_id) const; + const RemoteId& remote_id) const; // Helper functions to adjust service idle timeout duration. void SetServiceIdleHandler( mojo::Remote<printing::mojom::PrintBackendService>& service, bool sandboxed, - const std::string& remote_id, + const RemoteId& remote_id, const base::TimeDelta& timeout); - void UpdateServiceIdleTimeoutByRemoteId(const std::string& remote_id, + void UpdateServiceIdleTimeoutByRemoteId(const RemoteId& remote_id, const base::TimeDelta& timeout); // Callback when predetermined idle timeout occurs indicating no in-flight // messages for a short period of time. `sandboxed` is used to distinguish // which mapping of remotes the timeout applies to. - void OnIdleTimeout(bool sandboxed, const std::string& remote_id); + void OnIdleTimeout(bool sandboxed, const RemoteId& remote_id); // Callback when service has disconnected (e.g., process crashes). // `sandboxed` is used to distinguish which mapping of remotes the // disconnection applies to. - void OnRemoteDisconnected(bool sandboxed, const std::string& remote_id); + void OnRemoteDisconnected(bool sandboxed, const RemoteId& remote_id); // Helper function to choose correct saved callbacks mapping. RemoteSavedEnumeratePrintersCallbacks& @@ -379,14 +388,14 @@ // Helper functions to save outstanding callbacks. template <class... T, class... X> void SaveCallback(RemoteSavedCallbacks<T...>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, const base::UnguessableToken& saved_callback_id, base::OnceCallback<void(X...)> callback); // Helper functions for local callback wrappers for mojom calls. template <class... T, class... X> void ServiceCallbackDone(RemoteSavedCallbacks<T...>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, const base::UnguessableToken& saved_callback_id, X... data); @@ -427,11 +436,11 @@ template <class T> void RunSavedCallbacksStructResult( RemoteSavedStructCallbacks<T>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, mojo::StructPtr<T> result_to_clone); template <class... T> void RunSavedCallbacks(RemoteSavedCallbacks<T...>& saved_callbacks, - const std::string& remote_id, + const RemoteId& remote_id, T... result); // Test support for client ID management. @@ -525,6 +534,13 @@ // performing the operation with modified restrictions. base::flat_set<std::string> drivers_requiring_elevated_privilege_; +#if BUILDFLAG(IS_WIN) + // Support for process model where there can be multiple PrintBackendService + // instances. This is necessary because Windows printer drivers are not + // thread safe. Map key is a printer name. + base::flat_map<std::string, RemoteId> remote_id_map_; +#endif + // Crash key is kept at class level so that we can obtain printer driver // information for a prior call should the process be terminated due to Mojo // message response validation.
diff --git a/chrome/browser/printing/print_backend_service_manager_unittest.cc b/chrome/browser/printing/print_backend_service_manager_unittest.cc index 62545ca..5602f141a 100644 --- a/chrome/browser/printing/print_backend_service_manager_unittest.cc +++ b/chrome/browser/printing/print_backend_service_manager_unittest.cc
@@ -17,11 +17,12 @@ using ClientsSet = PrintBackendServiceManager::ClientsSet; using PrintClientsMap = PrintBackendServiceManager::PrintClientsMap; +using RemoteId = PrintBackendServiceManager::RemoteId; namespace { -constexpr char kRemoteIdEmpty[] = ""; -constexpr char kRemoteIdTestPrinter[] = "test-printer"; +const RemoteId kRemoteIdEmpty{1}; +const RemoteId kRemoteIdTestPrinter{2}; const ClientsSet kTestQueryNoClients; const ClientsSet kTestQueryWithOneClient{1};
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js index 48af186..4892db1 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
@@ -45,6 +45,7 @@ import {PanelBackground} from './panel/panel_background.js'; import {ChromeVoxPrefs} from './prefs.js'; import {RangeAutomationHandler} from './range_automation_handler.js'; +import {SmartStickyMode} from './smart_sticky_mode.js'; import {TtsBackground} from './tts_background.js'; /** @@ -135,6 +136,7 @@ PageLoadSoundHandler.init(); PanelBackground.init(); RangeAutomationHandler.init(); + SmartStickyMode.init(); // Allow all async initializers to run simultaneously, but wait for them to // complete before continuing.
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js index bc160a6..24132634 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -82,7 +82,6 @@ /** @private {boolean} */ this.languageLoggingEnabled_ = false; - SmartStickyMode.init(); this.init_(); }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js index 52a083f3..875c577 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js
@@ -672,57 +672,6 @@ } /** @override */ - formatNode_(data, token, tree, options) { - const buff = data.outputBuffer; - const node = data.node; - const formatLog = data.outputFormatLogger; - let prevNode = data.opt_prevNode; - - if (!tree.firstChild) { - return; - } - - const relationName = tree.firstChild.value; - if (relationName === 'tableCellColumnHeaders') { - // Skip output when previous position falls on the same column. - while (prevNode && !AutomationPredicate.cellLike(prevNode)) { - prevNode = prevNode.parent; - } - if (prevNode && - prevNode.tableCellColumnIndex === node.tableCellColumnIndex) { - return; - } - - const headers = node.tableCellColumnHeaders; - if (headers) { - for (let i = 0; i < headers.length; i++) { - const header = headers[i].name; - if (header) { - this.append_(buff, header, options); - formatLog.writeTokenWithValue(token, header); - } - } - } - } else if (relationName === 'tableCellRowHeaders') { - const headers = node.tableCellRowHeaders; - if (headers) { - for (let i = 0; i < headers.length; i++) { - const header = headers[i].name; - if (header) { - this.append_(buff, header, options); - formatLog.writeTokenWithValue(token, header); - } - } - } - } else if (node[relationName]) { - const related = node[relationName]; - this.node_( - related, related, outputTypes.OutputCustomEvent.NAVIGATE, buff, - formatLog); - } - } - - /** @override */ formatTextContent_(data, token, options) { const buff = data.outputBuffer; const node = data.node; @@ -1045,7 +994,7 @@ node, prevNode, type, buff, formatLog, {preferStart: preferStartOrEndAncestry}); } - this.node_(node, prevNode, type, buff, formatLog); + this.formatNode(node, prevNode, type, buff, formatLog); if (addContextAfter) { this.ancestry_( node, prevNode, type, buff, formatLog, @@ -1310,9 +1259,9 @@ * @param {!outputTypes.OutputEventType} type * @param {!Array<Spannable>} buff * @param {!OutputFormatLogger} formatLog - * @private + * @override */ - node_(node, prevNode, type, buff, formatLog) { + formatNode(node, prevNode, type, buff, formatLog) { const originalBuff = buff; if (this.formatOptions_.braille) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_formatter.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_formatter.js index 9031378d..8e9ff21b 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_formatter.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_formatter.js
@@ -99,7 +99,7 @@ } else if (token === 'cellIndexText') { this.formatCellIndexText_(this.params_, token, options); } else if (token === 'node') { - this.output_.formatNode_(this.params_, token, tree, options); + this.formatNode_(this.params_, token, tree, options); } else if (token === 'nameOrTextContent' || token === 'textContent') { this.output_.formatTextContent_(this.params_, token, options); } else if (this.params_.node[token] !== undefined) { @@ -507,6 +507,63 @@ /** * @param {!outputTypes.OutputFormattingData} data * @param {string} token + * @param {!OutputFormatTree} tree + * @param {!{annotation: Array<*>, isUnique: (boolean|undefined)}} options + * @private + */ + formatNode_(data, token, tree, options) { + const buff = data.outputBuffer; + const node = data.node; + const formatLog = data.outputFormatLogger; + let prevNode = data.opt_prevNode; + + if (!tree.firstChild) { + return; + } + + const relationName = tree.firstChild.value; + if (relationName === 'tableCellColumnHeaders') { + // Skip output when previous position falls on the same column. + while (prevNode && !AutomationPredicate.cellLike(prevNode)) { + prevNode = prevNode.parent; + } + if (prevNode && + prevNode.tableCellColumnIndex === node.tableCellColumnIndex) { + return; + } + + const headers = node.tableCellColumnHeaders; + if (headers) { + for (let i = 0; i < headers.length; i++) { + const header = headers[i].name; + if (header) { + this.output_.append_(buff, header, options); + formatLog.writeTokenWithValue(token, header); + } + } + } + } else if (relationName === 'tableCellRowHeaders') { + const headers = node.tableCellRowHeaders; + if (headers) { + for (let i = 0; i < headers.length; i++) { + const header = headers[i].name; + if (header) { + this.output_.append_(buff, header, options); + formatLog.writeTokenWithValue(token, header); + } + } + } + } else if (node[relationName]) { + const related = node[relationName]; + this.output_.formatNode( + related, related, outputTypes.OutputCustomEvent.NAVIGATE, buff, + formatLog); + } + } + + /** + * @param {!outputTypes.OutputFormattingData} data + * @param {string} token * @private */ formatPressed_(data, token) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_interface.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_interface.js index 7bae0e6..d041f78f 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_interface.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_interface.js
@@ -85,14 +85,6 @@ /** * @param {!outputTypes.OutputFormattingData} data - * @param {string} token - * @param {!OutputFormatTree} tree - * @param {!{annotation: Array<*>, isUnique: (boolean|undefined)}} options - */ - formatNode_(data, token, tree, options) {} - - /** - * @param {!outputTypes.OutputFormattingData} data */ formatPhoneticReading_(data) {} @@ -109,6 +101,15 @@ formatTextContent_(data, token, options) {} /** + * @param {!AutomationNode} node + * @param {!AutomationNode} prevNode + * @param {!outputTypes.OutputEventType} type + * @param {!Array<Spannable>} buff + * @param {!OutputFormatLogger} formatLog + */ + formatNode(node, prevNode, type, buff, formatLog) {} + + /** * Renders the given range using optional context previous range and event * type. * @param {!CursorRange} range
diff --git a/chrome/browser/resources/chromeos/drive_internals.html b/chrome/browser/resources/chromeos/drive_internals.html index 7cc3715..1609308f 100644 --- a/chrome/browser/resources/chromeos/drive_internals.html +++ b/chrome/browser/resources/chromeos/drive_internals.html
@@ -109,39 +109,33 @@ <section id="bulk-pinning-section" hidden> <h2>Bulk Pinning</h2> - <label> - Enable Bulk Pinning - <input type="checkbox" id="bulk-pinning-toggle"> - </label> <table> - <tr colspan="2"> - <td><progress id="bulk-pinning-progress"></progress></td> - </tr> <tr> - <th>Current Stage</th> + <th> + <label for="bulk-pinning-toggle">Enable</label> + </th> + <td> + <input type="checkbox" id="bulk-pinning-toggle"> + </td> + <tr> + <th>Stage</th> <td id="bulk-pinning-setup-stage">?</td> </tr> <tr> - <th>Setup Stage Error</th> + <th>Error</th> <td id="bulk-pinning-setup-stage-error">?</td> </tr> <tr> - <th>Available Space</th> - <td> - <span id="bulk-pinning-available-disk-space">?</span> MB - </td> + <th>Free Space</th> + <td id="bulk-pinning-available-disk-space">?</td> </tr> <tr> <th>Required Space</th> - <td> - <span id="bulk-pinning-required-disk-space">?</span> MB - </td> + <td id="bulk-pinning-required-disk-space">?</td> </tr> <tr> <th>Pinned Space</th> - <td> - <span id="bulk-pinning-pinned-disk-space">?</span> MB - </td> + <td id="bulk-pinning-pinned-disk-space">?</td> </tr> </table> </section>
diff --git a/chrome/browser/resources/chromeos/drive_internals.js b/chrome/browser/resources/chromeos/drive_internals.js index 9c6b291..bea7b23 100644 --- a/chrome/browser/resources/chromeos/drive_internals.js +++ b/chrome/browser/resources/chromeos/drive_internals.js
@@ -102,16 +102,11 @@ function updateBulkPinning(enabled) { $('bulk-pinning-toggle').checked = enabled; - if (enabled) { - return; - } $('bulk-pinning-setup-stage').innerText = '?'; $('bulk-pinning-setup-stage-error').innerText = '?'; $('bulk-pinning-available-disk-space').innerText = '?'; $('bulk-pinning-required-disk-space').innerText = '?'; $('bulk-pinning-pinned-disk-space').innerText = '?'; - $('bulk-pinning-progress').value = 0; - $('bulk-pinning-progress').max = 1; } function onBulkPinningProgress(progress) { @@ -120,17 +115,11 @@ return; } $('bulk-pinning-setup-stage').innerText = progress.stage; - if (progress.setupError) { - $('bulk-pinning-setup-stage-error').innerText = progress.setupError; - } + $('bulk-pinning-setup-stage-error').innerText = progress.setupError; $('bulk-pinning-available-disk-space').innerText = - toMegaByteString(Number(progress.availableDiskSpace)); - $('bulk-pinning-required-disk-space').innerText = - toMegaByteString(Number(progress.requiredDiskSpace)); - $('bulk-pinning-pinned-disk-space').innerText = - toMegaByteString(Number(progress.pinnedDiskSpace)); - $('bulk-pinning-progress').value = Number(progress.pinnedDiskSpace); - $('bulk-pinning-progress').max = Number(progress.requiredDiskSpace); + progress.availableDiskSpace; + $('bulk-pinning-required-disk-space').innerText = progress.requiredDiskSpace; + $('bulk-pinning-pinned-disk-space').innerText = progress.pinnedDiskSpace; } function updateStartupArguments(args) {
diff --git a/chrome/browser/resources/settings/chromeos/device_page/audio.html b/chrome/browser/resources/settings/chromeos/device_page/audio.html index 3318dc74..7fef6b2 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/audio.html +++ b/chrome/browser/resources/settings/chromeos/device_page/audio.html
@@ -154,7 +154,9 @@ </div> <div id="audioInputNoiseCancellationSubsection"> <div id="audioInputNoiseCancellationLabel">Noise Cancellation</div> - <cr-toggle id="audioInputNoiseCancellationToggle"></cr-toggle> + <cr-toggle id="audioInputNoiseCancellationToggle" + checked="{{isNoiseCancellationEnabled_}}"> + </cr-toggle> </div> </div> </div>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/audio.ts b/chrome/browser/resources/settings/chromeos/device_page/audio.ts index 5fb1c4e..e69e74df 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/audio.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/audio.ts
@@ -27,7 +27,7 @@ import {CrosAudioConfigInterface, getCrosAudioConfig} from './cros_audio_config.js'; // TODO(b/260277007): Update import to get `AudioSystemProperties` from // `cros_audio_config.mojom-webui.js` once mojo updated to handle audio input. -import {AudioSystemProperties, FakeCrosAudioConfig} from './fake_cros_audio_config.js'; +import {AudioDevice, AudioEffectState, AudioSystemProperties, FakeCrosAudioConfig} from './fake_cros_audio_config.js'; /** Utility for keeping percent in inclusive range of [0,100]. */ function clampPercent(percent: number): number { @@ -59,6 +59,12 @@ type: Boolean, reflectToAttribute: true, }, + + isNoiseCancellationEnabled_: { + type: Boolean, + observer: + SettingsAudioElement.prototype.onNoiseCancellationEnabledChanged, + }, }; } @@ -68,6 +74,7 @@ private crosAudioConfig_: CrosAudioConfigInterface; private isOutputMuted_: boolean; private isInputMuted_: boolean; + private isNoiseCancellationEnabled_: boolean; constructor() { super(); @@ -95,6 +102,11 @@ this.audioSystemProperties_.outputMuteState !== MuteState.kNotMuted; this.isInputMuted_ = this.audioSystemProperties_.inputMuteState !== MuteState.kNotMuted; + const activeInputDevice = this.audioSystemProperties_.inputDevices.find( + (device: AudioDevice) => device.isActive); + this.isNoiseCancellationEnabled_ = + (activeInputDevice?.noiseCancellationState === + AudioEffectState.ENABLED); } getIsOutputMutedForTest(): boolean { @@ -145,6 +157,18 @@ this.crosAudioConfig_.setActiveDevice(BigInt(inputDeviceSelect.value)); } + /** Handles updates to noise cancellation state. */ + protected onNoiseCancellationEnabledChanged( + enabled: SettingsAudioElement['isNoiseCancellationEnabled_']): void { + // TODO(b/260277007): Remove condition when setActiveDevice added to mojo + // definition. + if (!this.crosAudioConfig_.setNoiseCancellationEnabled) { + return; + } + + this.crosAudioConfig_.setNoiseCancellationEnabled(enabled); + } + /** * Handles the event where the input volume slider is being changed. */
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn index a9c555c8..b3e63e73 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -11,31 +11,12 @@ closure_flags = os_settings_closure_flags is_polymer3 = true deps = [ - ":apn_subpage", ":internet_page", ":internet_page_browser_proxy", ":internet_subpage", ] } -js_library("apn_subpage") { - deps = [ - "//ash/webui/common/resources:assert", - "//ash/webui/common/resources/network:apn_list", - "//ash/webui/common/resources/network:cellular_utils", - "//ash/webui/common/resources/network:mojo_interface_provider", - "//ash/webui/common/resources/network:network_listener_behavior", - "//ash/webui/common/resources/network:onc_mojo", - "//chrome/browser/resources/settings/chromeos:route_observer_behavior", - "//chrome/browser/resources/settings/chromeos:router", - "//chromeos/services/network_config/public/mojom:mojom_webui_js", - "//chromeos/services/network_config/public/mojom:network_types_webui_js", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] - - externs_list = [] -} - js_library("internet_page") { deps = [ ":internet_page_browser_proxy", @@ -98,7 +79,6 @@ html_to_js("web_components") { js_files = [ - "apn_subpage.js", "internet_page.js", "internet_subpage.js", ]
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/apn_subpage.js b/chrome/browser/resources/settings/chromeos/internet_page/apn_subpage.js deleted file mode 100644 index 947cd72..0000000 --- a/chrome/browser/resources/settings/chromeos/internet_page/apn_subpage.js +++ /dev/null
@@ -1,235 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview - * Settings subpage for managing APNs. - */ - -import './internet_shared.css.js'; -import 'chrome://resources/ash/common/network/apn_list.js'; - -import {assert} from 'chrome://resources/ash/common/assert.js'; -import {processDeviceState} from 'chrome://resources/ash/common/network/cellular_utils.js'; -import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js'; -import {NetworkListenerBehavior, NetworkListenerBehaviorInterface} from 'chrome://resources/ash/common/network/network_listener_behavior.js'; -import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; -import {CrosNetworkConfigRemote, ManagedCellularProperties, ManagedProperties, MAX_NUM_CUSTOM_APNS, NetworkStateProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; -import {NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; -import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {routes} from '../os_route.js'; -import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js'; -import {Route, Router} from '../router.js'; - -/** - * @constructor - * @extends {PolymerElement} - * @implements {NetworkListenerBehaviorInterface} - * @implements {RouteObserverBehaviorInterface} - */ -const ApnSubpageElementBase = mixinBehaviors( - [ - NetworkListenerBehavior, - RouteObserverBehavior, - ], - PolymerElement); - -/** @polymer */ -export class ApnSubpageElement extends ApnSubpageElementBase { - static get is() { - return 'apn-subpage'; - } - - static get template() { - return html`{__html_template__}`; - } - - static get properties() { - return { - /** @private The GUID of the network to display details for. */ - guid_: String, - - /** @private {!ManagedProperties|undefined} */ - managedProperties_: { - type: Object, - }, - - /** @private {?OncMojo.DeviceStateProperties} */ - deviceState_: { - type: Object, - value: null, - }, - - isNumCustomApnsLimitReached: { - type: Boolean, - notify: true, - value: false, - computed: 'computeIsNumCustomApnsLimitReached_(managedProperties_)', - }, - }; - } - - constructor() { - super(); - /** @private {!CrosNetworkConfigRemote} */ - this.networkConfig_ = - MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote(); - } - - close() { - // If the page is already closed, return early to avoid navigating backward - // erroneously. - if (!this.guid_) { - return; - } - - this.guid_ = ''; - this.managedProperties_ = undefined; - this.deviceState_ = null; - Router.getInstance().navigateToPreviousRoute(); - } - - /** - * RouteObserverBehavior - * @param {!Route} route - * @protected - */ - currentRouteChanged(route) { - if (route !== routes.APN) { - return; - } - - const queryParams = Router.getInstance().getQueryParameters(); - const guid = queryParams.get('guid') || ''; - if (!guid) { - console.warn('No guid specified for page:' + route); - Router.getInstance().navigateToPreviousRoute(); - return; - } - - this.guid_ = guid; - // Set default properties until they are loaded. - this.deviceState_ = null; - this.managedProperties_ = OncMojo.getDefaultManagedProperties( - NetworkType.kCellular, this.guid_, - OncMojo.getNetworkTypeString(NetworkType.kCellular)); - this.getNetworkDetails_(); - } - - /** - * CrosNetworkConfigObserver impl - * @param {!NetworkStateProperties} network - */ - onNetworkStateChanged(network) { - if (!this.guid_ || !this.managedProperties_) { - return; - } - if (network.guid === this.guid_) { - this.getNetworkDetails_(); - } - } - - /** CrosNetworkConfigObserver impl */ - onDeviceStateListChanged() { - if (!this.guid_ || !this.managedProperties_) { - return; - } - this.getDeviceState_(); - } - - /** - * Helper method that can be used by parent elements to open the APN - * creation dialog. - */ - openApnDetailDialogInCreateMode() { - assert(!!this.guid_); - assert(!!this.$.apnList); - this.$.apnList.openApnDetailDialogInCreateMode(); - } - - /** @private */ - getNetworkDetails_() { - assert(this.guid_); - this.networkConfig_.getManagedProperties(this.guid_).then(response => { - // Details page was closed while request was in progress, ignore the - // result. - if (!this.guid_) { - return; - } - - if (!response.result) { - // Close the page if the network was removed and no longer exists. - this.close(); - return; - } - - if (!this.isCellular_(response.result)) { - // Close the page if there are no cellular properties. - this.close(); - return; - } - - if (this.deviceState_ && this.deviceState_.scanning) { - // Cellular properties may be invalid while scanning, so keep the - // existing properties instead. - response.result.typeProperties.cellular = - this.managedProperties_.typeProperties.cellular; - } - this.managedProperties_ = response.result; - - if (!this.deviceState_) { - this.getDeviceState_(); - } - }); - } - - /** @private */ - getDeviceState_() { - if (!this.isCellular_(this.managedProperties_)) { - return; - } - const type = this.managedProperties_.type; - this.networkConfig_.getDeviceStateList().then(response => { - // If there is no GUID, the page was closed between requesting the device - // state and receiving it. If this occurs, there is no need to process the - // response. Note that if this subpage is reopened later, we'll request - // this data again. - if (!this.guid_) { - return; - } - - const {deviceState, shouldGetNetworkDetails} = - processDeviceState(type, response.result, this.deviceState_); - - this.deviceState_ = deviceState; - if (shouldGetNetworkDetails) { - this.getNetworkDetails_(); - } - }); - } - - /** - * @param {!ManagedProperties|undefined} managedProperties - * @return {boolean} - * @private - */ - isCellular_(managedProperties) { - return !!managedProperties && - managedProperties.type === NetworkType.kCellular; - } - - /** - * @return {boolean} - * @private - */ - computeIsNumCustomApnsLimitReached_() { - return this.isCellular_(this.managedProperties_) && - !!this.managedProperties_.typeProperties.cellular.customApnList && - this.managedProperties_.typeProperties.cellular.customApnList.length >= - MAX_NUM_CUSTOM_APNS; - } -} - -customElements.define(ApnSubpageElement.is, ApnSubpageElement);
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/apn_subpage.ts b/chrome/browser/resources/settings/chromeos/internet_page/apn_subpage.ts new file mode 100644 index 0000000..e33983a --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/internet_page/apn_subpage.ts
@@ -0,0 +1,225 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * Settings subpage for managing APNs. + */ + +import './internet_shared.css.js'; +import 'chrome://resources/ash/common/network/apn_list.js'; + +import {ApnList} from 'chrome://resources/ash/common/network/apn_list.js'; +import {processDeviceState} from 'chrome://resources/ash/common/network/cellular_utils.js'; +import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js'; +import {NetworkListenerBehavior, NetworkListenerBehaviorInterface} from 'chrome://resources/ash/common/network/network_listener_behavior.js'; +import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; +import {CrosNetworkConfigRemote, ManagedProperties, MAX_NUM_CUSTOM_APNS, NetworkStateProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; +import {NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; +import {mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {routes} from '../os_route.js'; +import {RouteObserverMixin, RouteObserverMixinInterface} from '../route_observer_mixin.js'; +import {Route, Router} from '../router.js'; + +import {getTemplate} from './apn_subpage.html.js'; + +export interface ApnSubpageElement { + $: { + apnList: ApnList, + }; +} + +const ApnSubpageElementBase = mixinBehaviors( + [ + NetworkListenerBehavior, + ], + RouteObserverMixin(PolymerElement)) as { + new (): PolymerElement & RouteObserverMixinInterface & + NetworkListenerBehaviorInterface, +}; + +export class ApnSubpageElement extends ApnSubpageElementBase { + static get is() { + return 'apn-subpage' as const; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + /** The GUID of the network to display details for. */ + guid_: String, + + isNumCustomApnsLimitReached: { + type: Boolean, + notify: true, + value: false, + computed: 'computeIsNumCustomApnsLimitReached_(managedProperties_)', + }, + + managedProperties_: { + type: Object, + }, + + deviceState_: { + type: Object, + value: null, + }, + }; + } + + isNumCustomApnsLimitReached: boolean; + private deviceState_: OncMojo.DeviceStateProperties|null; + private guid_: string; + private managedProperties_: ManagedProperties|undefined; + private networkConfig_: CrosNetworkConfigRemote; + + constructor() { + super(); + this.networkConfig_ = + MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote(); + } + + close(): void { + // If the page is already closed, return early to avoid navigating backward + // erroneously. + if (!this.guid_) { + return; + } + + this.guid_ = ''; + this.managedProperties_ = undefined; + this.deviceState_ = null; + Router.getInstance().navigateToPreviousRoute(); + } + + override currentRouteChanged(route: Route): void { + if (route !== routes.APN) { + return; + } + + const queryParams = Router.getInstance().getQueryParameters(); + const guid = queryParams.get('guid') || ''; + if (!guid) { + console.warn('No guid specified for page:' + route); + Router.getInstance().navigateToPreviousRoute(); + return; + } + + this.guid_ = guid; + // Set default properties until they are loaded. + this.deviceState_ = null; + this.managedProperties_ = OncMojo.getDefaultManagedProperties( + NetworkType.kCellular, this.guid_, + OncMojo.getNetworkTypeString(NetworkType.kCellular)); + this.getNetworkDetails_(); + } + + override onNetworkStateChanged(network: NetworkStateProperties): void { + if (!this.guid_ || !this.managedProperties_) { + return; + } + if (network.guid === this.guid_) { + this.getNetworkDetails_(); + } + } + + override onDeviceStateListChanged(): void { + if (!this.guid_ || !this.managedProperties_) { + return; + } + this.getDeviceState_(); + } + + /** + * Helper method that can be used by parent elements to open the APN + * creation dialog. + */ + openApnDetailDialogInCreateMode() { + assert(this.guid_); + this.$.apnList.openApnDetailDialogInCreateMode(); + } + + private async getNetworkDetails_(): Promise<void> { + assert(this.guid_); + + const response = await this.networkConfig_.getManagedProperties(this.guid_); + // Details page was closed while request was in progress, ignore the + // result. + if (!this.guid_) { + return; + } + + if (!response.result) { + // Close the page if the network was removed and no longer exists. + this.close(); + return; + } + + if (!this.isCellular_(response.result)) { + // Close the page if there are no cellular properties. + this.close(); + return; + } + + if (this.deviceState_ && this.deviceState_.scanning) { + // Cellular properties may be invalid while scanning, so keep the + // existing properties instead. + response.result.typeProperties.cellular = + this.managedProperties_!.typeProperties.cellular; + } + this.managedProperties_ = response.result; + + if (!this.deviceState_) { + this.getDeviceState_(); + } + } + + private async getDeviceState_(): Promise<void> { + if (!this.isCellular_(this.managedProperties_)) { + return; + } + const type = this.managedProperties_!.type; + const response = await this.networkConfig_.getDeviceStateList(); + // If there is no GUID, the page was closed between requesting the device + // state and receiving it. If this occurs, there is no need to process the + // response. Note that if this subpage is reopened later, we'll request + // this data again. + if (!this.guid_) { + return; + } + + const {deviceState, shouldGetNetworkDetails} = + processDeviceState(type, response.result, this.deviceState_); + + this.deviceState_ = deviceState; + if (shouldGetNetworkDetails) { + this.getNetworkDetails_(); + } + } + + private isCellular_(managedProperties: ManagedProperties|undefined): boolean { + return !!managedProperties && + managedProperties.type === NetworkType.kCellular; + } + + private computeIsNumCustomApnsLimitReached_(): boolean { + return this.isCellular_(this.managedProperties_) && + !!this.managedProperties_!.typeProperties.cellular!.customApnList && + this.managedProperties_!.typeProperties.cellular!.customApnList + .length >= MAX_NUM_CUSTOM_APNS; + } +} + +declare global { + interface HTMLElementTagNameMap { + [ApnSubpageElement.is]: ApnSubpageElement; + } +} + +customElements.define(ApnSubpageElement.is, ApnSubpageElement);
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js index 45b1d4bb..cacc54de 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
@@ -18,10 +18,11 @@ import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js'; import '../../prefs/prefs.js'; +import '../../settings_shared.css.js'; import '../os_settings_page/os_settings_animated_pages.js'; import '../os_settings_page/os_settings_subpage.js'; -import '../../settings_shared.css.js'; import '../os_settings_icons.css.js'; +import './apn_subpage.js'; import './cellular_setup_dialog.js'; import './internet_config.js'; import './internet_detail_menu.js'; @@ -54,7 +55,6 @@ import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js'; import {Route, Router} from '../router.js'; -import {ApnSubpageElement} from './apn_subpage'; import {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page_browser_proxy.js'; // TODO(crbug/1315757) The following type definitions are only needed for @@ -93,6 +93,13 @@ InternetConfigElement.prototype.type; InternetConfigElement.prototype.open = function() {}; +/** + * @constructor + * @extends {HTMLElement} + */ +function ApnSubpageElement() {} +ApnSubpageElement.prototype.openApnDetailDialogInCreateMode = function() {}; + /** @type {number} */ const ESIM_PROFILE_LIMIT = 5;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html index 389a62e3..b49f5be 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html
@@ -33,6 +33,6 @@ <div class="cr-row" id="browserSettings"> <localized-link class="secondary" localized-string="$i18n{appNotificationsLinkToBrowserSettingsDescription}" - link-url="$i18n{appNotificationsBrowserSettingsURL}"> + on-link-clicked="onBrowserSettingsLinkClicked_"> </localized-link> </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.ts b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.ts index 0ccb3d9..90d1c7d 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.ts
@@ -203,6 +203,15 @@ private alphabeticalSort_(first: App, second: App): number { return first.title!.localeCompare(second.title!); } + + private onBrowserSettingsLinkClicked_(event: CustomEvent<{event: Event}>): + void { + // Prevent the default link click behavior. + event.detail.event.preventDefault(); + + // Programmatically open browser settings. + this.mojoInterfaceProvider_.openBrowserNotificationSettings(); + } } declare global {
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.ts b/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.ts index 53b6d63..2376144f 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.ts +++ b/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.ts
@@ -88,7 +88,7 @@ } private onSearchEngineLinkClick_() { - window.open('chrome://settings/search'); + this.browserProxy_.openBrowserSearchSettings(); } private getBrowserSearchSettingsLink_() {
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.ts b/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.ts index e9438d5..e1c0c4e 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.ts +++ b/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.ts
@@ -44,6 +44,7 @@ export interface SearchEnginesBrowserProxy { setDefaultSearchEngine(modelIndex: number): void; getSearchEnginesList(): Promise<SearchEnginesInfo>; + openBrowserSearchSettings(): void; } let instance: SearchEnginesBrowserProxy|null = null; @@ -65,4 +66,8 @@ getSearchEnginesList() { return sendWithPromise('getSearchEnginesList'); } + + openBrowserSearchSettings() { + chrome.send('openBrowserSearchSettings'); + } }
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 4f860ce..42ad0044 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -59,6 +59,7 @@ "chromeos/guest_os/guest_os_shared_paths.ts", "chromeos/guest_os/guest_os_shared_usb_devices.ts", "chromeos/guest_os/guest_os_shared_usb_devices_add_dialog.ts", + "chromeos/internet_page/apn_subpage.ts", "chromeos/internet_page/cellular_networks_list.ts", "chromeos/internet_page/cellular_roaming_toggle_button.ts", "chromeos/internet_page/cellular_setup_dialog.ts", @@ -374,7 +375,6 @@ # Files that are generated by html_to_js() or other build rule. generated_web_component_files = [ - "chromeos/internet_page/apn_subpage.js", "chromeos/internet_page/internet_page.js", "chromeos/internet_page/internet_subpage.js", "chromeos/multidevice_page/multidevice_combined_setup_item.js",
diff --git a/chrome/browser/resources/side_panel/bookmarks/bookmarks_api_proxy.ts b/chrome/browser/resources/side_panel/bookmarks/bookmarks_api_proxy.ts index f663ac7..c4a9c61 100644 --- a/chrome/browser/resources/side_panel/bookmarks/bookmarks_api_proxy.ts +++ b/chrome/browser/resources/side_panel/bookmarks/bookmarks_api_proxy.ts
@@ -13,6 +13,11 @@ callbackRouter: {[key: string]: ChromeEvent<Function>}; bookmarkCurrentTabInFolder(folderId: string): void; cutBookmark(id: string): void; + contextMenuOpenBookmarkInNewTab(id: string, source: ActionSource): void; + contextMenuOpenBookmarkInNewWindow(id: string, source: ActionSource): void; + contextMenuOpenBookmarkInIncognitoWindow(id: string, source: ActionSource): + void; + contextMenuDelete(id: string, source: ActionSource): void; copyBookmark(id: string): Promise<void>; createFolder(parentId: string, title: string): void; deleteBookmarks(ids: string[]): Promise<void>; @@ -57,6 +62,22 @@ chrome.bookmarkManagerPrivate.cut([id]); } + contextMenuOpenBookmarkInNewTab(id: string, source: ActionSource) { + this.handler.executeOpenInNewTabCommand(BigInt(id), source); + } + + contextMenuOpenBookmarkInNewWindow(id: string, source: ActionSource) { + this.handler.executeOpenInNewWindowCommand(BigInt(id), source); + } + + contextMenuOpenBookmarkInIncognitoWindow(id: string, source: ActionSource) { + this.handler.executeOpenInIncognitoWindowCommand(BigInt(id), source); + } + + contextMenuDelete(id: string, source: ActionSource) { + this.handler.executeDeleteCommand(BigInt(id), source); + } + copyBookmark(id: string) { return new Promise<void>(resolve => { chrome.bookmarkManagerPrivate.copy([id], resolve);
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.html b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.html index 68bbfeb..0ca96fc3 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.html +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.html
@@ -11,9 +11,14 @@ </style> <cr-action-menu id="menu"> - <template is="dom-repeat" items="[[menuItems_]]"> - <button class="dropdown-item" on-click="onMenuItemClicked_"> - [[item]] - </button> + <template is="dom-repeat" items="[[getMenuItemsForBookmark_(bookmark_)]]"> + <template is="dom-if" if="[[!showDivider_(item)]]" restamp> + <button class="dropdown-item" on-click="onMenuItemClicked_"> + [[item.label]] + </button> + </template> + <template is="dom-if" if="[[showDivider_(item)]]" restamp> + <hr> + </template> </template> </cr-action-menu>
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.ts index 4658bee9..abb506a 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.ts +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_context_menu.ts
@@ -22,6 +22,19 @@ }; } +export enum MenuItemId { + OPEN_NEW_TAB = 0, + OPEN_NEW_WINDOW = 1, + OPEN_INCOGNITO = 2, + DELETE = 3, + DIVIDER = 4, +} + +export interface MenuItem { + id: MenuItemId; + label?: string; +} + export class PowerBookmarksContextMenuElement extends PolymerElement { static get is() { return 'power-bookmarks-context-menu'; @@ -36,11 +49,6 @@ bookmark_: Object, depth_: Number, - - menuItems_: { - type: Array, - value: () => [loadTimeData.getString('menuOpenNewTab')], - }, }; } @@ -48,7 +56,6 @@ BookmarksApiProxyImpl.getInstance(); private bookmark_: chrome.bookmarks.BookmarkTreeNode; private depth_: number; - private menuItems_: string[]; showAt( event: MouseEvent, bookmark: chrome.bookmarks.BookmarkTreeNode, @@ -66,21 +73,57 @@ this.$.menu.showAtPosition({top: event.clientY, left: event.clientX}); } - private onMenuItemClicked_(event: DomRepeatEvent<string>) { + private getMenuItemsForBookmark_(): MenuItem[] { + const menuItems: MenuItem[] = [ + { + id: MenuItemId.OPEN_NEW_TAB, + label: loadTimeData.getString('menuOpenNewTab'), + }, + { + id: MenuItemId.OPEN_NEW_WINDOW, + label: loadTimeData.getString('menuOpenNewWindow'), + }, + ]; + + if (!loadTimeData.getBoolean('incognitoMode')) { + menuItems.push({ + id: MenuItemId.OPEN_INCOGNITO, + label: loadTimeData.getString('menuOpenIncognito'), + }); + } + + menuItems.push( + {id: MenuItemId.DIVIDER}, + {id: MenuItemId.DELETE, label: loadTimeData.getString('tooltipDelete')}, + ); + + return menuItems; + } + + private showDivider_(menuItem: MenuItem): boolean { + return menuItem.id === MenuItemId.DIVIDER; + } + + private onMenuItemClicked_(event: DomRepeatEvent<MenuItem>) { event.preventDefault(); event.stopPropagation(); - switch (event.model.index) { - case 0: - // Open in new tab - this.bookmarksApi_.openBookmark( - this.bookmark_!.id, this.depth_, { - middleButton: true, - altKey: false, - ctrlKey: false, - metaKey: false, - shiftKey: false, - }, - ActionSource.kBookmark); + switch (event.model.item.id) { + case MenuItemId.OPEN_NEW_TAB: + this.bookmarksApi_.contextMenuOpenBookmarkInNewTab( + this.bookmark_!.id, ActionSource.kBookmark); + break; + case MenuItemId.OPEN_NEW_WINDOW: + this.bookmarksApi_.contextMenuOpenBookmarkInNewWindow( + this.bookmark_!.id, ActionSource.kBookmark); + break; + case MenuItemId.OPEN_INCOGNITO: + this.bookmarksApi_.contextMenuOpenBookmarkInIncognitoWindow( + this.bookmark_!.id, ActionSource.kBookmark); + break; + case MenuItemId.DELETE: + this.bookmarksApi_.contextMenuDelete( + this.bookmark_!.id, ActionSource.kBookmark); + break; } this.$.menu.close(); }
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java index c2a5724d..8d26727 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -9,8 +9,6 @@ import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; -import android.os.Build; -import android.os.Build.VERSION_CODES; import android.view.View; import androidx.appcompat.content.res.AppCompatResources; @@ -290,7 +288,7 @@ mOrderedFirstPartyOptions.add(createScreenshotFirstPartyOption()); // TODO(crbug.com/1250871): Long Screenshots on by default; supported on Android 7.0+. if (ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT) - && mTabProvider.hasValue() && Build.VERSION.SDK_INT >= VERSION_CODES.N) { + && mTabProvider.hasValue()) { mOrderedFirstPartyOptions.add(createLongScreenshotsFirstPartyOption()); } mOrderedFirstPartyOptions.add(createCopyLinkFirstPartyOption());
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java index 1f251ff..d3af6c7b 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
@@ -12,7 +12,6 @@ import static org.mockito.ArgumentMatchers.anyString; import android.app.Activity; -import android.os.Build; import android.support.test.runner.lifecycle.Stage; import android.view.View; @@ -323,10 +322,7 @@ // Long Screenshots is supported >= Android N (7.0). List<String> expectedModels = new ArrayList<String>(); expectedModels.add(mActivity.getResources().getString(R.string.sharing_screenshot)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - expectedModels.add( - mActivity.getResources().getString(R.string.sharing_long_screenshot)); - } + expectedModels.add(mActivity.getResources().getString(R.string.sharing_long_screenshot)); expectedModels.addAll(ImmutableList.of( mActivity.getResources().getString(R.string.sharing_copy_url), mActivity.getResources().getString(R.string.sharing_copy_image), @@ -349,10 +345,7 @@ List<String> expectedModels = new ArrayList<String>(); expectedModels.add(mActivity.getResources().getString(R.string.sharing_screenshot)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - expectedModels.add( - mActivity.getResources().getString(R.string.sharing_long_screenshot)); - } + expectedModels.add(mActivity.getResources().getString(R.string.sharing_long_screenshot)); expectedModels.addAll(ImmutableList.of( mActivity.getResources().getString(R.string.sharing_copy_image), mActivity.getResources().getString(R.string.send_tab_to_self_share_activity_title),
diff --git a/chrome/browser/ssl/https_upgrades_browsertest.cc b/chrome/browser/ssl/https_upgrades_browsertest.cc index fcf1665..e75472da 100644 --- a/chrome/browser/ssl/https_upgrades_browsertest.cc +++ b/chrome/browser/ssl/https_upgrades_browsertest.cc
@@ -44,14 +44,33 @@ using security_interstitials::https_only_mode::Event; using security_interstitials::https_only_mode::kEventHistogram; +// Many of the following tests have only minor variations for HTTPS-First Mode +// vs. HTTPS-Upgrades. These get parameterized so the tests run under both +// versions on their own as well as when both HTTPS Upgrades and HTTPS-First +// Mode are enabled (to test any interactions between the two upgrade modes). +enum class HttpsUpgradesTestType { + kHttpsFirstModeOnly, + kHttpsUpgradesOnly, + kBoth +}; + // Tests for the v2 implementation of HTTPS-First Mode. -class HttpsUpgradesBrowserTest : public InProcessBrowserTest { +class HttpsUpgradesBrowserTest + : public testing::WithParamInterface<HttpsUpgradesTestType>, + public InProcessBrowserTest { public: HttpsUpgradesBrowserTest() = default; ~HttpsUpgradesBrowserTest() override = default; void SetUp() override { - feature_list_.InitAndEnableFeature(features::kHttpsFirstModeV2); + if (GetParam() != HttpsUpgradesTestType::kHttpsFirstModeOnly) { + feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kHttpsFirstModeV2, + features::kHttpsUpgrades}, + /*disabled_features=*/{}); + } else { + feature_list_.InitAndEnableFeature(features::kHttpsFirstModeV2); + } InProcessBrowserTest::SetUp(); } @@ -81,7 +100,13 @@ HttpsOnlyModeUpgradeInterceptor::SetHttpPortForTesting( http_server()->port()); - SetPref(true); + // For the kHttpsUpgradesOnly test variant, don't enable the HTTPS-First + // Mode pref. + if (GetParam() == HttpsUpgradesTestType::kHttpsUpgradesOnly) { + SetPref(false); + } else { + SetPref(true); + } } void TearDownOnMainThread() override { SetPref(false); } @@ -131,6 +156,13 @@ content::NavigateToURLBlockUntilNavigationsComplete(tab, url, 2); } + // Whether the tests should run steps that assume the HTTP interstitial will + // trigger (i.e., for fallback HTTP navigations when HTTPS-First Mode is + // enabled). + bool IsHttpInterstitialEnabled() const { + return GetParam() != HttpsUpgradesTestType::kHttpsUpgradesOnly; + } + net::EmbeddedTestServer* http_server() { return &http_server_; } net::EmbeddedTestServer* https_server() { return &https_server_; } base::HistogramTester* histograms() { return &histograms_; } @@ -143,9 +175,28 @@ base::HistogramTester histograms_; }; +INSTANTIATE_TEST_SUITE_P( + /* no prefix */, + HttpsUpgradesBrowserTest, + ::testing::Values(HttpsUpgradesTestType::kHttpsFirstModeOnly, + HttpsUpgradesTestType::kHttpsUpgradesOnly, + HttpsUpgradesTestType::kBoth), + // Map param to a human-readable string for better test output. + [](testing::TestParamInfo<HttpsUpgradesTestType> input_type) + -> std::string { + switch (input_type.param) { + case HttpsUpgradesTestType::kHttpsFirstModeOnly: + return "HttpsFirstModeOnly"; + case HttpsUpgradesTestType::kHttpsUpgradesOnly: + return "HttpsUpgradesOnly"; + case HttpsUpgradesTestType::kBoth: + return "BothHttpsFirstModeAndHttpsUpgrades"; + } + }); + // If the user navigates to an HTTP URL for a site that supports HTTPS, the // navigation should end up on the HTTPS version of the URL. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UrlWithHttpScheme_ShouldUpgrade) { GURL http_url = http_server()->GetURL("foo.test", "/simple.html"); GURL https_url = https_server()->GetURL("foo.test", "/simple.html"); @@ -169,7 +220,7 @@ // If the user navigates to an HTTPS URL for a site that supports HTTPS, the // navigation should end up on that exact URL. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UrlWithHttpsScheme_ShouldLoad) { GURL https_url = https_server()->GetURL("foo.test", "/simple.html"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -182,7 +233,7 @@ // If the user navigates to a localhost URL, the navigation should end up on // that exact URL. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, Localhost_ShouldNotUpgrade) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, Localhost_ShouldNotUpgrade) { GURL localhost_url = http_server()->GetURL("localhost", "/simple.html"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(content::NavigateToURL(contents, localhost_url)); @@ -194,14 +245,18 @@ // If the user navigates to an HTTPS URL, the navigation should end up on that // exact URL, even if the site has an SSL error. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UrlWithHttpsScheme_BrokenSSL_ShouldNotFallback) { GURL https_url = https_server()->GetURL("bad-https.test", "/simple.html"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_FALSE(content::NavigateToURL(contents, https_url)); EXPECT_EQ(https_url, contents->GetLastCommittedURL()); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents)); + + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingSSLInterstitial(contents)); + } // Verify that navigation event metrics were not recorded as the navigation // was not upgraded. @@ -211,7 +266,7 @@ // If the user navigates to an HTTP URL for a site with broken HTTPS, the // navigation should end up on the HTTPS URL and show the HTTPS-Only Mode // interstitial. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UrlWithHttpScheme_BrokenSSL_ShouldInterstitial) { GURL http_url = http_server()->GetURL("bad-https.test", "/simple.html"); GURL https_url = https_server()->GetURL("bad-https.test", "/simple.html"); @@ -220,8 +275,11 @@ NavigateAndWaitForFallback(contents, http_url); EXPECT_EQ(http_url, contents->GetLastCommittedURL()); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } // Verify that navigation event metrics were correctly recorded. histograms()->ExpectTotalCount(kEventHistogram, 3); @@ -232,18 +290,32 @@ // If the user triggers an HTTPS-Only Mode interstitial for a host and then // clicks through the interstitial, they should end up on the HTTP URL. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialBypassed_HttpFallbackLoaded) { GURL http_url = http_server()->GetURL("bad-https.test", "/simple.html"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); NavigateAndWaitForFallback(contents, http_url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); - // Proceed through the interstitial, which will add the host to the allowlist - // and navigate to the HTTP fallback URL. - ProceedThroughInterstitial(contents); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + + // Proceed through the interstitial, which will add the host to the + // allowlist and navigate to the HTTP fallback URL. + ProceedThroughInterstitial(contents); + + // Verify that the interstitial metrics were correctly recorded. + histograms()->ExpectTotalCount("interstitial.https_first_mode.decision", 2); + histograms()->ExpectBucketCount( + "interstitial.https_first_mode.decision", + security_interstitials::MetricsHelper::Decision::SHOW, 1); + histograms()->ExpectBucketCount( + "interstitial.https_first_mode.decision", + security_interstitials::MetricsHelper::Decision::PROCEED, 1); + } + EXPECT_EQ(http_url, contents->GetLastCommittedURL()); // Verify that navigation event metrics were correctly recorded. @@ -251,20 +323,11 @@ histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1); histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1); histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1); - - // Verify that the interstitial metrics were correctly recorded. - histograms()->ExpectTotalCount("interstitial.https_first_mode.decision", 2); - histograms()->ExpectBucketCount( - "interstitial.https_first_mode.decision", - security_interstitials::MetricsHelper::Decision::SHOW, 1); - histograms()->ExpectBucketCount( - "interstitial.https_first_mode.decision", - security_interstitials::MetricsHelper::Decision::PROCEED, 1); } // If the upgraded HTTPS URL is not available due to a net error, it should // trigger the HTTPS-Only Mode interstitial and offer fallback. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, NetErrorOnUpgrade_ShouldInterstitial) { GURL http_url = http_server()->GetURL("foo.test", "/close-socket"); GURL https_url = https_server()->GetURL("foo.test", "/close-socket"); @@ -273,8 +336,11 @@ NavigateAndWaitForFallback(contents, http_url); EXPECT_EQ(http_url, contents->GetLastCommittedURL()); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } // Verify that navigation event metrics were correctly recorded. histograms()->ExpectTotalCount(kEventHistogram, 3); @@ -285,7 +351,7 @@ // Navigations in subframes should not get upgraded by HTTPS-Only Mode. They // should be blocked as mixed content. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpsParentHttpSubframeNavigation_Blocked) { const GURL parent_url( https_server()->GetURL("foo.test", "/iframe_blank.html")); @@ -306,7 +372,7 @@ // Navigating to an HTTP URL in a subframe of an HTTP page should not upgrade // the subframe navigation to HTTPS (even if the subframe navigation is to a // different host than the parent frame). -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpParentHttpSubframeNavigation_NotUpgraded) { // The parent frame will fail to upgrade to HTTPS. const GURL parent_url( @@ -317,10 +383,14 @@ auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); NavigateAndWaitForFallback(contents, parent_url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); - // Proceeding through the interstitial will add the hostname to the allowlist. - ProceedThroughInterstitial(contents); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + // Proceeding through the interstitial will add the hostname to the + // allowlist. + ProceedThroughInterstitial(contents); + } // Verify that navigation event metrics were recorded for the main frame. histograms()->ExpectTotalCount(kEventHistogram, 3); @@ -339,23 +409,38 @@ // Tests that a navigation to the HTTP version of a site with an HTTPS version // that is slow to respond gets upgraded to HTTPS but times out and shows the // HTTPS-Only Mode interstitial. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, SlowHttps_ShouldInterstitial) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, SlowHttps_ShouldInterstitial) { // Set timeout to zero so that HTTPS upgrades immediately timeout. HttpsOnlyModeNavigationThrottle::set_timeout_for_testing(0); - const GURL http_url = http_server()->GetURL("foo.test", "/hung"); + // Set up a custom HTTPS server that times out without sending a response. + net::EmbeddedTestServer timeout_server{net::EmbeddedTestServer::TYPE_HTTPS}; + timeout_server.RegisterRequestHandler(base::BindLambdaForTesting( + [&](const net::test_server::HttpRequest& request) + -> std::unique_ptr<net::test_server::HttpResponse> { + // Server will hang until destroyed. + return std::make_unique<net::test_server::HungResponse>(); + })); + ASSERT_TRUE(timeout_server.Start()); + HttpsOnlyModeUpgradeInterceptor::SetHttpsPortForTesting( + timeout_server.port()); + + const GURL http_url = http_server()->GetURL("foo.test", "/simple.html"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); NavigateAndWaitForFallback(contents, http_url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } EXPECT_EQ(http_url, contents->GetLastCommittedURL()); } // Tests that an HTTP POST form navigation to "bar.test" from an HTTP page on // "foo.test" is not upgraded to HTTPS. (HTTP form navigations from HTTPS are // blocked by the Mixed Forms warning.) -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, HttpPageHttpPost_NotUpgraded) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpPageHttpPost_NotUpgraded) { // Point the HTTP form target to "bar.test". base::StringPairs replacement_text; replacement_text.emplace_back(make_pair( @@ -365,16 +450,19 @@ auto replacement_path = net::test_server::GetFilePathWithReplacements( "/ssl/page_with_form_targeting_http_url.html", replacement_text); - // Navigate to the page hosting the form on "foo.test". The HTTPS-Only Mode - // interstitial should trigger. + // Navigate to the page hosting the form on "foo.test". auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); content::NavigateToURLBlockUntilNavigationsComplete( contents, http_server()->GetURL("bad-https.test", replacement_path), 2); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); - // Proceed through the interstitial to add the hostname to the allowlist. - ProceedThroughInterstitial(contents); + if (IsHttpInterstitialEnabled()) { + // The HTTPS-Only Mode interstitial should trigger. + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + // Proceed through the interstitial to add the hostname to the allowlist. + ProceedThroughInterstitial(contents); + } // Verify that navigation event metrics were recorded for the initial page. histograms()->ExpectTotalCount(kEventHistogram, 3); @@ -397,7 +485,7 @@ // Tests that if an HTTPS navigation redirects to HTTP on a different host, it // should upgrade to HTTPS on that new host. (A downgrade redirect on the same // host would imply a redirect loop.) -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpsToHttpRedirect_ShouldUpgrade) { GURL target_url = http_server()->GetURL("bar.test", "/title1.html"); GURL url = https_server()->GetURL("foo.test", @@ -425,7 +513,7 @@ // Tests that navigating to an HTTPS page that downgrades to HTTP on the same // host will fail and trigger the HTTPS-Only Mode interstitial (due to the // redirect loop hitting the redirect limit). -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, RedirectLoop_ShouldInterstitial) { // Set up a new test server instance so it can have a custom handler. net::EmbeddedTestServer downgrading_server{ @@ -456,8 +544,12 @@ GURL url = downgrading_server.GetURL("foo.test", "/"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); NavigateAndWaitForFallback(contents, url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } // Verify that navigation event metrics were correctly recorded. histograms()->ExpectTotalCount(kEventHistogram, 3); @@ -469,25 +561,29 @@ // Tests that the security level is WARNING when the HTTPS-Only Mode // interstitial is shown for a net error on HTTPS. (Without HTTPS-Only Mode, a // net error would be a security level of NONE.) -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, NetErrorOnUpgrade_SecurityLevelWarning) { GURL http_url = http_server()->GetURL("foo.test", "/close-socket"); GURL https_url = https_server()->GetURL("foo.test", "/close-socket"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); + auto* helper = SecurityStateTabHelper::FromWebContents(contents); NavigateAndWaitForFallback(contents, http_url); EXPECT_EQ(http_url, contents->GetLastCommittedURL()); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); - auto* helper = SecurityStateTabHelper::FromWebContents(contents); - EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel()); + EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel()); - // Proceed through the interstitial to navigate to the HTTP site. The HTTP - // site results in a net error, which should have security level NONE (as no - // connection was made). - ProceedThroughInterstitial(contents); + // Proceed through the interstitial to navigate to the HTTP site. + ProceedThroughInterstitial(contents); + } + + // The HTTP site results in a net error, which should have security level NONE + // (as no connection was made). EXPECT_EQ(security_state::NONE, helper->GetSecurityLevel()); } @@ -495,24 +591,28 @@ // interstitial is shown for a cert error on HTTPS. (Without HTTPS-Only Mode, a // a cert error would be a security level of DANGEROUS.) After clicking through // the interstitial, the security level should still be WARNING. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, BrokenSSLOnUpgrade_SecurityLevelWarning) { GURL http_url = http_server()->GetURL("bad-https.test", "/simple.html"); GURL https_url = https_server()->GetURL("bad-https.test", "/simple.html"); auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); + auto* helper = SecurityStateTabHelper::FromWebContents(contents); NavigateAndWaitForFallback(contents, http_url); EXPECT_EQ(http_url, contents->GetLastCommittedURL()); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); - auto* helper = SecurityStateTabHelper::FromWebContents(contents); - EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel()); + EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel()); - // Proceed through the interstitial to navigate to the HTTP page. The security - // level should still be WARNING. - ProceedThroughInterstitial(contents); + // Proceed through the interstitial to navigate to the HTTP page. + ProceedThroughInterstitial(contents); + } + + // The security level should still be WARNING. EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel()); } @@ -526,7 +626,7 @@ // be shown and the user should be able to click through the SSL interstitial to // visit the HTTPS version of the site (but in a DANGEROUS security level // state). -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpsUpgradeWithBrokenSSL_ShouldTriggerSSLInterstitial) { // Set up a new test server instance so it can have a custom handler that // redirects to the HTTPS server. @@ -554,16 +654,20 @@ auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); NavigateAndWaitForFallback(contents, http_url); - EXPECT_EQ(http_url, contents->GetLastCommittedURL()); - // The HTTPS-First Mode interstitial should trigger first. - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + if (IsHttpInterstitialEnabled()) { + // The HTTPS-First Mode interstitial should trigger first. + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); - // Proceeding through the HTTPS-First Mode interstitial will hit the upgrading - // server's HTTP->HTTPS redirect. This should result in an SSL interstitial - // (not an HTTPS-First Mode interstitial). - ProceedThroughInterstitial(contents); + // Proceeding through the HTTPS-First Mode interstitial will hit the + // upgrading server's HTTP->HTTPS redirect. This should result in an SSL + // interstitial (not an HTTPS-First Mode interstitial). + ProceedThroughInterstitial(contents); + } + + EXPECT_EQ(https_url, contents->GetLastCommittedURL()); EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents)); // Proceeding through the SSL interstitial should navigate to the HTTPS @@ -581,18 +685,25 @@ histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1); histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1); - // Verify that the interstitial metrics were correctly recorded. - histograms()->ExpectBucketCount( - "interstitial.https_first_mode.decision", - security_interstitials::MetricsHelper::Decision::SHOW, 1); - histograms()->ExpectBucketCount( - "interstitial.https_first_mode.decision", - security_interstitials::MetricsHelper::Decision::PROCEED, 1); + if (IsHttpInterstitialEnabled()) { + // Verify that the interstitial metrics were correctly recorded. + histograms()->ExpectBucketCount( + "interstitial.https_first_mode.decision", + security_interstitials::MetricsHelper::Decision::SHOW, 1); + histograms()->ExpectBucketCount( + "interstitial.https_first_mode.decision", + security_interstitials::MetricsHelper::Decision::PROCEED, 1); + } } // Tests that clicking the "Learn More" link in the HTTPS-First Mode // interstitial opens a new tab for the help center article. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, InterstitialLearnMoreLink) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialLearnMoreLink) { + // This test is only relevant to HTTPS-First Mode. + if (!IsHttpInterstitialEnabled()) { + return; + } + GURL http_url = http_server()->GetURL("foo.test", "/close-socket"); GURL https_url = https_server()->GetURL("foo.test", "/close-socket"); @@ -631,7 +742,13 @@ // later the server fixes their HTTPS support and the user successfully connects // over HTTPS, the allowlist entry is cleared (so HFM will kick in again for // that site). -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, BadHttpsFollowedByGoodHttps) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, BadHttpsFollowedByGoodHttps) { + // TODO(crbug.com/1394910): This test is flakey when only HTTPS Upgrades are + // enabled. + if (!IsHttpInterstitialEnabled()) { + return; + } + GURL http_url = http_server()->GetURL("foo.test", "/close-socket"); GURL bad_https_url = https_server()->GetURL("foo.test", "/close-socket"); GURL good_https_url = https_server()->GetURL("foo.test", "/ssl/google.html"); @@ -649,9 +766,12 @@ // Navigate to `http_url`, which will get upgraded to `bad_https_url`. NavigateAndWaitForFallback(tab, http_url); - ASSERT_TRUE( - chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(tab)); - ProceedThroughInterstitial(tab); + if (IsHttpInterstitialEnabled()) { + ASSERT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(tab)); + ProceedThroughInterstitial(tab); + } + EXPECT_TRUE(state->HasAllowException( http_url.host(), tab->GetPrimaryMainFrame()->GetStoragePartition())); @@ -673,9 +793,12 @@ // Navigate to `http_url`, which will get upgraded to `bad_https_url`. NavigateAndWaitForFallback(tab, http_url); - ASSERT_TRUE( - chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(tab)); - ProceedThroughInterstitial(tab); + if (IsHttpInterstitialEnabled()) { + ASSERT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(tab)); + ProceedThroughInterstitial(tab); + } + EXPECT_TRUE(state->HasAllowException( http_url.host(), tab->GetPrimaryMainFrame()->GetStoragePartition())); @@ -698,7 +821,12 @@ // Tests that clicking the "Go back" button in the HTTPS-First Mode interstitial // navigates back to the previous page (about:blank in this case). -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, InterstitialGoBack) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialGoBack) { + // This test is only relevant to HTTPS-First Mode. + if (!IsHttpInterstitialEnabled()) { + return; + } + GURL http_url = http_server()->GetURL("foo.test", "/close-socket"); GURL https_url = https_server()->GetURL("foo.test", "/close-socket"); @@ -725,7 +853,12 @@ // Tests that closing the tab of the HTTPS-First Mode interstitial counts as // not proceeding through the interstitial for metrics. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, CloseInterstitialTab) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, CloseInterstitialTab) { + // This test is only relevant to HTTPS-First Mode. + if (!IsHttpInterstitialEnabled()) { + return; + } + GURL http_url = http_server()->GetURL("foo.test", "/close-socket"); GURL https_url = https_server()->GetURL("foo.test", "/close-socket"); @@ -751,7 +884,7 @@ // Tests that if a user allowlists a host and then does not visit it again for // seven days (the expiration period), then the interstitial will be shown again // the next time they visit the host. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, AllowlistEntryExpires) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, AllowlistEntryExpires) { content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); @@ -773,9 +906,14 @@ // through the HTTPS-First Mode interstitial to allowlist the host. GURL http_url = http_server()->GetURL("bad-https.test", "/simple.html"); NavigateAndWaitForFallback(contents, http_url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); - ProceedThroughInterstitial(contents); + + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + ProceedThroughInterstitial(contents); + } + EXPECT_EQ(http_url, contents->GetLastCommittedURL()); EXPECT_TRUE(state->IsHttpAllowedForHost( http_url.host(), contents->GetPrimaryMainFrame()->GetStoragePartition())); @@ -789,13 +927,17 @@ EXPECT_FALSE(state->IsHttpAllowedForHost( http_url.host(), contents->GetPrimaryMainFrame()->GetStoragePartition())); NavigateAndWaitForFallback(contents, http_url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); + + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + } } // Tests that re-visiting an allowlisted host bumps the expiration time to a new // seven days in the future from now. -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, RevisitingBumpsExpiration) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, RevisitingBumpsExpiration) { content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); @@ -817,9 +959,14 @@ // through the HTTPS-First Mode interstitial to allowlist the host. GURL http_url = http_server()->GetURL("bad-https.test", "/simple.html"); NavigateAndWaitForFallback(contents, http_url); - EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( - contents)); - ProceedThroughInterstitial(contents); + + if (IsHttpInterstitialEnabled()) { + EXPECT_TRUE( + chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( + contents)); + ProceedThroughInterstitial(contents); + } + EXPECT_EQ(http_url, contents->GetLastCommittedURL()); EXPECT_TRUE(state->IsHttpAllowedForHost( http_url.host(), contents->GetPrimaryMainFrame()->GetStoragePartition())); @@ -846,7 +993,7 @@ // Tests that if a hostname has an HSTS entry registered, then HTTPS-First Mode // should not try to upgrade it (instead allowing HSTS to handle the upgrade as // it is more strict). -IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, PreferHstsOverHttpsFirstMode) { +IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, PreferHstsOverHttpsFirstMode) { content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); @@ -893,6 +1040,11 @@ // linux-bfcache-rel bots). IN_PROC_BROWSER_TEST_F(HttpsUpgradesBrowserTest, DISABLED_InterstitialFallbackMaintainsHistory) { + // This test only applies to HTTPS-First Mode. + if (!IsHttpInterstitialEnabled()) { + return; + } + GURL good_https_url = https_server()->GetURL("site1.test", "/defaultresponse"); @@ -950,8 +1102,8 @@ auto* helper = SecurityStateTabHelper::FromWebContents(contents); EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel()); - // Simulate clicking the browser "forward" button. (The HistoryGoForward() - // call returns `false` because it is an error page.) + // Simulate clicking the browser "forward" button. The HistoryGoForward() + // call returns `false` because it is an error page. EXPECT_FALSE(content::HistoryGoForward(contents)); EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL()); EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( @@ -967,8 +1119,7 @@ // Repeat forward one last time. (Previously the user would no longer be able // to go back any more as the history entries were lost.) - // The HistoryGoForward() call returns `false` because it is an error page. - EXPECT_FALSE(content::HistoryGoForward(contents)); + EXPECT_FALSE(content::HistoryGoForward(contents)); // error page -> false EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL()); EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial( contents));
diff --git a/chrome/browser/ssl/https_upgrades_interceptor.cc b/chrome/browser/ssl/https_upgrades_interceptor.cc index 955bb9d..a22761e 100644 --- a/chrome/browser/ssl/https_upgrades_interceptor.cc +++ b/chrome/browser/ssl/https_upgrades_interceptor.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ssl/https_only_mode_tab_helper.h" #include "chrome/browser/ssl/https_only_mode_upgrade_url_loader.h" #include "chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" @@ -39,6 +40,8 @@ // Only serve upgrade redirects for main frame, GET requests to HTTP URLs. This // excludes "localhost" (and loopback addresses) as they do not expose traffic // over the network. +// TODO(crbug.com/1394910): Extend the exemption list for HTTPS-Upgrades +// beyond just localhost. bool ShouldCreateLoader(const network::ResourceRequest& resource_request, HttpsOnlyModeTabHelper* tab_helper) { if (resource_request.is_outermost_main_frame && @@ -72,9 +75,18 @@ return; } - // Don't upgrade if the HTTPS-First Mode setting isn't enabled. + // TODO(crbug.com/1394910): Check for HttpsUpgrades and HttpsAllowlist + // enterprise policies as well. It might be best to consolidate these checks + // into the HttpsUpgradesNavigationThrottle which sees the navigation first. auto* prefs = profile->GetPrefs(); - if (!prefs || !prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled)) { + bool https_first_mode_enabled = + base::FeatureList::IsEnabled(features::kHttpsFirstModeV2) && prefs && + prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled); + bool https_upgrades_enabled = + base::FeatureList::IsEnabled(features::kHttpsUpgrades) || + https_first_mode_enabled; + if (!https_upgrades_enabled) { + // Don't upgrade the request and let the default loader continue. std::move(callback).Run({}); return; } @@ -103,6 +115,9 @@ } // Don't upgrade navigation if it is allowlisted. + // TODO(crbug.com/1394910): Distinguish HTTPS-First Mode and HTTPS-Upgrades + // allowlist entries, and ensure that HTTPS-Upgrades allowlist entries don't + // downgrade Page Info. StatefulSSLHostStateDelegate* state = static_cast<StatefulSSLHostStateDelegate*>( profile->GetSSLHostStateDelegate());
diff --git a/chrome/browser/ssl/https_upgrades_navigation_throttle.cc b/chrome/browser/ssl/https_upgrades_navigation_throttle.cc index a425532e..da37c67 100644 --- a/chrome/browser/ssl/https_upgrades_navigation_throttle.cc +++ b/chrome/browser/ssl/https_upgrades_navigation_throttle.cc
@@ -5,14 +5,18 @@ #include "chrome/browser/ssl/https_upgrades_navigation_throttle.h" #include "base/feature_list.h" +#include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" +#include "base/task/sequenced_task_runner.h" #include "base/time/time.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/https_only_mode_tab_helper.h" #include "chrome/browser/ssl/https_upgrades_navigation_throttle.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" +#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" #include "components/security_interstitials/core/https_only_mode_metrics.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" @@ -29,6 +33,8 @@ base::TimeDelta g_fallback_delay = base::Seconds(3); // Helper to record an HTTPS-First Mode navigation event. +// TODO(crbug.com/1394910): Rename these metrics now that they apply to both +// HTTPS-First Mode and HTTPS Upgrades. void RecordHttpsFirstModeNavigation( security_interstitials::https_only_mode::Event event) { base::UmaHistogramEnumeration( @@ -52,8 +58,13 @@ return nullptr; } - if (!base::FeatureList::IsEnabled(features::kHttpsOnlyMode) || !prefs || - !prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled)) { + bool https_first_mode_enabled = + base::FeatureList::IsEnabled(features::kHttpsFirstModeV2) && prefs && + prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled); + bool https_upgrades_enabled = + https_first_mode_enabled || + base::FeatureList::IsEnabled(features::kHttpsUpgrades); + if (!https_upgrades_enabled) { return nullptr; } @@ -65,25 +76,28 @@ HttpsOnlyModeTabHelper::CreateForWebContents(handle->GetWebContents()); return std::make_unique<HttpsUpgradesNavigationThrottle>( - handle, std::move(blocking_page_factory)); + handle, std::move(blocking_page_factory), https_first_mode_enabled); } HttpsUpgradesNavigationThrottle::HttpsUpgradesNavigationThrottle( content::NavigationHandle* handle, - std::unique_ptr<SecurityBlockingPageFactory> blocking_page_factory) + std::unique_ptr<SecurityBlockingPageFactory> blocking_page_factory, + bool http_interstitial_enabled) : content::NavigationThrottle(handle), - blocking_page_factory_(std::move(blocking_page_factory)) {} + blocking_page_factory_(std::move(blocking_page_factory)), + http_interstitial_enabled_(http_interstitial_enabled) {} HttpsUpgradesNavigationThrottle::~HttpsUpgradesNavigationThrottle() = default; content::NavigationThrottle::ThrottleCheckResult HttpsUpgradesNavigationThrottle::WillStartRequest() { - // If the navigation is fallback to HTTP, trigger the interstitial. + // If the navigation is fallback to HTTP, trigger the HTTP interstitial (if + // enabled). auto* handle = navigation_handle(); auto* contents = handle->GetWebContents(); auto* tab_helper = HttpsOnlyModeTabHelper::FromWebContents(contents); if (tab_helper->is_navigation_fallback() && - !handle->GetURL().SchemeIsCryptographic()) { + !handle->GetURL().SchemeIsCryptographic() && http_interstitial_enabled_) { std::unique_ptr<security_interstitials::HttpsOnlyModeBlockingPage> blocking_page = blocking_page_factory_->CreateHttpsOnlyModeBlockingPage( contents, handle->GetURL()); @@ -114,7 +128,7 @@ return content::NavigationThrottle::PROCEED; } - // Only show the interstitial if the Interceptor attempted to upgrade the + // Only fallback to HTTP if the Interceptor attempted to upgrade the // navigation. auto* contents = handle->GetWebContents(); auto* tab_helper = HttpsOnlyModeTabHelper::FromWebContents(contents); @@ -129,6 +143,25 @@ RecordHttpsFirstModeNavigation(Event::kUpgradeNetError); } + // If HTTPS-First Mode is not enabled (so no interstitial will be shown), + // add the hostname to the allowlist now before triggering fallback. + // HTTPS-First Mode handles this on the user proceeding through the + // interstitial only. + if (!http_interstitial_enabled_) { + Profile* profile = + Profile::FromBrowserContext(contents->GetBrowserContext()); + StatefulSSLHostStateDelegate* state = + static_cast<StatefulSSLHostStateDelegate*>( + profile->GetSSLHostStateDelegate()); + // StatefulSSLHostStateDelegate can be null during tests. + if (state) { + state->AllowHttpForHost( + handle->GetURL().host(), + contents->GetPrimaryMainFrame()->GetStoragePartition()); + } + tab_helper->set_is_navigation_upgraded(false); + } + // Mark the navigation as fallback and trigger a new navigation to the // fallback URL. tab_helper->set_is_navigation_fallback(true);
diff --git a/chrome/browser/ssl/https_upgrades_navigation_throttle.h b/chrome/browser/ssl/https_upgrades_navigation_throttle.h index e31f9f64..802e2e5 100644 --- a/chrome/browser/ssl/https_upgrades_navigation_throttle.h +++ b/chrome/browser/ssl/https_upgrades_navigation_throttle.h
@@ -33,7 +33,8 @@ HttpsUpgradesNavigationThrottle( content::NavigationHandle* handle, - std::unique_ptr<SecurityBlockingPageFactory> blocking_page_factory); + std::unique_ptr<SecurityBlockingPageFactory> blocking_page_factory, + bool http_interstitial_enabled); ~HttpsUpgradesNavigationThrottle() override; HttpsUpgradesNavigationThrottle(const HttpsUpgradesNavigationThrottle&) = @@ -54,6 +55,10 @@ private: std::unique_ptr<SecurityBlockingPageFactory> blocking_page_factory_; + + // Whether the throttle should trigger the interstitial warning before + // navigating to the HTTP fallback URL. + bool http_interstitial_enabled_; }; #endif // CHROME_BROWSER_SSL_HTTPS_UPGRADES_NAVIGATION_THROTTLE_H_
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 46aec62..f757adba 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1993,6 +1993,8 @@ "../ash/app_list/arc/arc_app_list_prefs_factory.h", "../ash/app_list/arc/arc_app_scoped_pref_update.cc", "../ash/app_list/arc/arc_app_scoped_pref_update.h", + "../ash/app_list/arc/arc_app_sync_metrics_helper.cc", + "../ash/app_list/arc/arc_app_sync_metrics_helper.h", "../ash/app_list/arc/arc_app_utils.cc", "../ash/app_list/arc/arc_app_utils.h", "../ash/app_list/arc/arc_data_removal_dialog.h",
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogBridge.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogBridge.java index d5387641..e4d4c98b 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogBridge.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogBridge.java
@@ -5,10 +5,8 @@ package org.chromium.chrome.browser.ui.autofill; import android.content.Context; -import android.os.Build.VERSION_CODES; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -73,7 +71,6 @@ * @param otpLength The expected length of the OTP. This is used for showing a hint in the input * field as well as some basic error handling. */ - @RequiresApi(api = VERSION_CODES.N) @CalledByNative void showDialog(int otpLength) { mDialogCoordinator.show(otpLength); @@ -84,7 +81,6 @@ * * @param errorMessage The error message to be displayed below the OTP input field. */ - @RequiresApi(api = VERSION_CODES.N) @CalledByNative void showOtpErrorMessage(String errorMessage) { mDialogCoordinator.showOtpErrorMessage(errorMessage);
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogCoordinator.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogCoordinator.java index bf48b9f9..10e7f6ce 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogCoordinator.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogCoordinator.java
@@ -9,11 +9,9 @@ import static org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.OTP_LENGTH; import android.content.Context; -import android.os.Build.VERSION_CODES; import android.view.LayoutInflater; import android.view.View; -import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; @@ -87,7 +85,6 @@ * * @param otpLength The expected length of the OTP input field. */ - @RequiresApi(api = VERSION_CODES.N) void show(int otpLength) { PropertyModel otpVerificationDialogModel = buildOtpVerificationDialogModel(otpLength); PropertyModelChangeProcessor.create( @@ -100,7 +97,6 @@ * * @param errorMessage The string that is displayed in the error message. */ - @RequiresApi(api = VERSION_CODES.N) void showOtpErrorMessage(String errorMessage) { mMediator.showOtpErrorMessage(Optional.of(errorMessage)); } @@ -127,7 +123,6 @@ * @param otpLength The only non-static state of the dialog, needs to be passed in so that it * can be added to the model. */ - @RequiresApi(api = VERSION_CODES.N) private PropertyModel buildOtpVerificationDialogModel(int otpLength) { return new PropertyModel.Builder(ALL_KEYS) .with(OTP_LENGTH, otpLength)
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogMediator.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogMediator.java index 9ed1cdb..48eeb367 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogMediator.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogMediator.java
@@ -12,11 +12,8 @@ import static org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.SHOW_PROGRESS_BAR_OVERLAY; import static org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.VIEW_DELEGATE; -import android.os.Build.VERSION_CODES; import android.os.Handler; -import androidx.annotation.RequiresApi; - import org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogCoordinator.Delegate; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -44,7 +41,6 @@ mDelegate.onDialogDismissed(); } - @RequiresApi(api = VERSION_CODES.N) @Override public void onClick(PropertyModel model, int buttonType) { switch (buttonType) { @@ -64,7 +60,6 @@ } } - @RequiresApi(api = VERSION_CODES.N) @Override public void onTextChanged(CharSequence s) { mModalDialogModel.set(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, @@ -73,7 +68,6 @@ mOtpVerificationDialogModel.set(EDIT_TEXT, Optional.of(s)); } - @RequiresApi(api = VERSION_CODES.N) @Override public void onResendLinkClicked() { clearEditText(); @@ -97,7 +91,6 @@ } /** Clear the text in the Edit Text field. */ - @RequiresApi(api = VERSION_CODES.N) void clearEditText() { mOtpVerificationDialogModel.set(EDIT_TEXT, Optional.empty()); } @@ -112,7 +105,6 @@ } /** Show an error message for the submitted otp. */ - @RequiresApi(api = VERSION_CODES.N) void showOtpErrorMessage(Optional<String> errorMessage) { mOtpVerificationDialogModel.set(SHOW_PROGRESS_BAR_OVERLAY, false); mOtpVerificationDialogModel.set(OTP_ERROR_MESSAGE, errorMessage);
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java index 51928b1e1..91f4d77 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java
@@ -7,7 +7,6 @@ import static org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.ANIMATION_DURATION_MS; import android.content.Context; -import android.os.Build.VERSION_CODES; import android.text.Editable; import android.text.SpannableString; import android.text.TextWatcher; @@ -18,8 +17,6 @@ import android.widget.RelativeLayout; import android.widget.TextView; -import androidx.annotation.RequiresApi; - import org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.ViewDelegate; import org.chromium.chrome.browser.ui.autofill.internal.R; import org.chromium.ui.text.NoUnderlineClickableSpan; @@ -72,7 +69,6 @@ * * @param viewDelegate The view delegate for this specific view. */ - @RequiresApi(api = VERSION_CODES.N) void setViewDelegate(ViewDelegate viewDelegate) { mOtpEditText.addTextChangedListener(buildTextWatcher(viewDelegate)); mOtpResendMessageTextView.setText(buildOtpResendMessageLink(getContext(), viewDelegate)); @@ -107,7 +103,6 @@ * @param errorMessage The error message that gets displayed to the user. Can be empty, * indicating there should be no error message shown on the dialog (so we hide it). */ - @RequiresApi(api = VERSION_CODES.N) void showOtpErrorMessage(Optional<String> errorMessage) { mOtpErrorMessageTextView.setVisibility(View.VISIBLE); mOtpErrorMessageTextView.setText(errorMessage.get()); @@ -151,7 +146,6 @@ } /** Builds Otp Resend Message Link **/ - @RequiresApi(api = VERSION_CODES.N) private SpannableString buildOtpResendMessageLink(Context context, ViewDelegate viewDelegate) { return SpanApplier.applySpans( context.getResources().getString(
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogViewBinder.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogViewBinder.java index 494db3a..dd7ad16 100644 --- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogViewBinder.java +++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogViewBinder.java
@@ -11,10 +11,6 @@ import static org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.SHOW_PROGRESS_BAR_OVERLAY; import static org.chromium.chrome.browser.ui.autofill.OtpVerificationDialogProperties.VIEW_DELEGATE; -import android.os.Build.VERSION_CODES; - -import androidx.annotation.RequiresApi; - import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -24,7 +20,6 @@ class OtpVerificationDialogViewBinder { private OtpVerificationDialogViewBinder() {} - @RequiresApi(api = VERSION_CODES.N) static void bind( PropertyModel model, OtpVerificationDialogView dialogView, PropertyKey propertyKey) { if (propertyKey.equals(EDIT_TEXT)) {
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn index 76a9c5df..39ecac9 100644 --- a/chrome/browser/ui/android/omnibox/BUILD.gn +++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -271,16 +271,16 @@ "java/res/drawable-hdpi/btn_suggestion_refine.png", "java/res/drawable-hdpi/ic_history_googblue_24dp.png", "java/res/drawable-hdpi/ic_suggestion_magnifier.png", - "java/res/drawable-ldrtl-hdpi-v17/btn_suggestion_refine.png", - "java/res/drawable-ldrtl-hdpi-v17/ic_suggestion_magnifier.png", - "java/res/drawable-ldrtl-mdpi-v17/btn_suggestion_refine.png", - "java/res/drawable-ldrtl-mdpi-v17/ic_suggestion_magnifier.png", - "java/res/drawable-ldrtl-xhdpi-v17/btn_suggestion_refine.png", - "java/res/drawable-ldrtl-xhdpi-v17/ic_suggestion_magnifier.png", - "java/res/drawable-ldrtl-xxhdpi-v17/btn_suggestion_refine.png", - "java/res/drawable-ldrtl-xxhdpi-v17/ic_suggestion_magnifier.png", - "java/res/drawable-ldrtl-xxxhdpi-v17/btn_suggestion_refine.png", - "java/res/drawable-ldrtl-xxxhdpi-v17/ic_suggestion_magnifier.png", + "java/res/drawable-ldrtl-hdpi/btn_suggestion_refine.png", + "java/res/drawable-ldrtl-hdpi/ic_suggestion_magnifier.png", + "java/res/drawable-ldrtl-mdpi/btn_suggestion_refine.png", + "java/res/drawable-ldrtl-mdpi/ic_suggestion_magnifier.png", + "java/res/drawable-ldrtl-xhdpi/btn_suggestion_refine.png", + "java/res/drawable-ldrtl-xhdpi/ic_suggestion_magnifier.png", + "java/res/drawable-ldrtl-xxhdpi/btn_suggestion_refine.png", + "java/res/drawable-ldrtl-xxhdpi/ic_suggestion_magnifier.png", + "java/res/drawable-ldrtl-xxxhdpi/btn_suggestion_refine.png", + "java/res/drawable-ldrtl-xxxhdpi/ic_suggestion_magnifier.png", "java/res/drawable-mdpi/bookmark_edit_active.png", "java/res/drawable-mdpi/btn_mic.png", "java/res/drawable-mdpi/btn_star.png",
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi-v17/btn_suggestion_refine.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi/btn_suggestion_refine.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi-v17/btn_suggestion_refine.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi/btn_suggestion_refine.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi-v17/ic_suggestion_magnifier.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi/ic_suggestion_magnifier.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi-v17/ic_suggestion_magnifier.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-hdpi/ic_suggestion_magnifier.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi-v17/btn_suggestion_refine.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi/btn_suggestion_refine.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi-v17/btn_suggestion_refine.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi/btn_suggestion_refine.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi-v17/ic_suggestion_magnifier.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi/ic_suggestion_magnifier.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi-v17/ic_suggestion_magnifier.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-mdpi/ic_suggestion_magnifier.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi-v17/btn_suggestion_refine.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi/btn_suggestion_refine.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi-v17/btn_suggestion_refine.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi/btn_suggestion_refine.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi-v17/ic_suggestion_magnifier.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi/ic_suggestion_magnifier.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi-v17/ic_suggestion_magnifier.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xhdpi/ic_suggestion_magnifier.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi-v17/btn_suggestion_refine.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi/btn_suggestion_refine.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi-v17/btn_suggestion_refine.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi/btn_suggestion_refine.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi-v17/ic_suggestion_magnifier.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi/ic_suggestion_magnifier.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi-v17/ic_suggestion_magnifier.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxhdpi/ic_suggestion_magnifier.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi-v17/btn_suggestion_refine.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi/btn_suggestion_refine.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi-v17/btn_suggestion_refine.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi/btn_suggestion_refine.png Binary files differ
diff --git a/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi-v17/ic_suggestion_magnifier.png b/chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi/ic_suggestion_magnifier.png similarity index 100% rename from chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi-v17/ic_suggestion_magnifier.png rename to chrome/browser/ui/android/omnibox/java/res/drawable-ldrtl-xxxhdpi/ic_suggestion_magnifier.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn index b188c7ca..7c61bc95 100644 --- a/chrome/browser/ui/android/toolbar/BUILD.gn +++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -97,7 +97,6 @@ "java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinator.java", "java/src/org/chromium/chrome/browser/toolbar/top/Toolbar.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarActionModeCallback.java", - "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarColorObserverManager.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java", @@ -205,12 +204,12 @@ "java/res/drawable-hdpi/incognito_switch.png", "java/res/drawable-hdpi/modern_location_bar.9.png", "java/res/drawable-hdpi/popup_bg_bottom.9.png", - "java/res/drawable-ldrtl-hdpi-v17/btn_toolbar_reload.png", - "java/res/drawable-ldrtl-mdpi-v17/btn_toolbar_reload.png", - "java/res/drawable-ldrtl-sw600dp-xhdpi-v17/toolbar_background.9.png", - "java/res/drawable-ldrtl-xhdpi-v17/btn_toolbar_reload.png", - "java/res/drawable-ldrtl-xxhdpi-v17/btn_toolbar_reload.png", - "java/res/drawable-ldrtl-xxxhdpi-v17/btn_toolbar_reload.png", + "java/res/drawable-ldrtl-hdpi/btn_toolbar_reload.png", + "java/res/drawable-ldrtl-mdpi/btn_toolbar_reload.png", + "java/res/drawable-ldrtl-sw600dp-xhdpi/toolbar_background.9.png", + "java/res/drawable-ldrtl-xhdpi/btn_toolbar_reload.png", + "java/res/drawable-ldrtl-xxhdpi/btn_toolbar_reload.png", + "java/res/drawable-ldrtl-xxxhdpi/btn_toolbar_reload.png", "java/res/drawable-mdpi/badge_update_dark.png", "java/res/drawable-mdpi/badge_update_light.png", "java/res/drawable-mdpi/btn_tabswitcher_modern.png",
diff --git a/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-hdpi-v17/btn_toolbar_reload.png b/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-hdpi/btn_toolbar_reload.png similarity index 100% rename from chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-hdpi-v17/btn_toolbar_reload.png rename to chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-hdpi/btn_toolbar_reload.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-mdpi-v17/btn_toolbar_reload.png b/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-mdpi/btn_toolbar_reload.png similarity index 100% rename from chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-mdpi-v17/btn_toolbar_reload.png rename to chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-mdpi/btn_toolbar_reload.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-sw600dp-xhdpi-v17/toolbar_background.9.png b/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-sw600dp-xhdpi/toolbar_background.9.png similarity index 100% rename from chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-sw600dp-xhdpi-v17/toolbar_background.9.png rename to chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-sw600dp-xhdpi/toolbar_background.9.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xhdpi-v17/btn_toolbar_reload.png b/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xhdpi/btn_toolbar_reload.png similarity index 100% rename from chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xhdpi-v17/btn_toolbar_reload.png rename to chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xhdpi/btn_toolbar_reload.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxhdpi-v17/btn_toolbar_reload.png b/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxhdpi/btn_toolbar_reload.png similarity index 100% rename from chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxhdpi-v17/btn_toolbar_reload.png rename to chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxhdpi/btn_toolbar_reload.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxxhdpi-v17/btn_toolbar_reload.png b/chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxxhdpi/btn_toolbar_reload.png similarity index 100% rename from chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxxhdpi-v17/btn_toolbar_reload.png rename to chrome/browser/ui/android/toolbar/java/res/drawable-ldrtl-xxxhdpi/btn_toolbar_reload.png Binary files differ
diff --git a/chrome/browser/ui/android/toolbar/java/res/values/styles.xml b/chrome/browser/ui/android/toolbar/java/res/values/styles.xml index c863a2e..2eb5bddd 100644 --- a/chrome/browser/ui/android/toolbar/java/res/values/styles.xml +++ b/chrome/browser/ui/android/toolbar/java/res/values/styles.xml
@@ -36,5 +36,7 @@ <item name="android:layout_width">@dimen/split_toolbar_button_width</item> <item name="android:background">@android:color/transparent</item> </style> - <style name="NavigationPopupDialog" parent="Widget.AppCompat.Light.ListPopupWindow" /> + <style name="NavigationPopupDialog" parent="Widget.AppCompat.Light.ListPopupWindow"> + <item name="android:popupElevation">0dp</item> + </style> </resources>
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java index 1b27e34..a5ede195 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@@ -70,8 +70,7 @@ boolean isTabToGtsAnimationEnabled, boolean isTabGroupsAndroidContinuationEnabled, BooleanSupplier isIncognitoModeEnabledSupplier, Callback<LoadUrlParams> logoClickedCallback, boolean isRefactorEnabled, - boolean shouldCreateLogoInToolbar, Callback<Boolean> finishedTransitionCallback, - ToolbarColorObserverManager toolbarColorObserverManager) { + boolean shouldCreateLogoInToolbar, Callback<Boolean> finishedTransitionCallback) { mStub = startSurfaceToolbarStub; mPropertyModel = @@ -103,7 +102,7 @@ isTabToGtsFadeAnimationEnabled, isTabGroupsAndroidContinuationEnabled, isIncognitoModeEnabledSupplier, logoClickedCallback, isRefactorEnabled, StartSurfaceConfiguration.IS_DOODLE_SUPPORTED.getValue(), shouldCreateLogoInToolbar, - finishedTransitionCallback, toolbarColorObserverManager); + finishedTransitionCallback); mThemeColorProvider = provider; mMenuButtonCoordinator = menuButtonCoordinator;
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java index e87b9aa1..27c99fb 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java
@@ -27,11 +27,9 @@ import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.TRANSLATION_Y; import android.animation.Animator; -import android.animation.ObjectAnimator; import android.content.Context; import android.view.View; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; @@ -50,7 +48,6 @@ import org.chromium.chrome.browser.toolbar.ButtonDataProvider; import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator; -import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.ToolbarAlphaInOverviewObserver; import org.chromium.chrome.browser.user_education.IPHCommandBuilder; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurfaceState; @@ -97,11 +94,9 @@ private boolean mIsNativeInitializedForLogo; private LogoCoordinator mLogoCoordinator; - private ObjectAnimator mAlphaAnimator; + private Animator mAlphaAnimator; private Callback<Boolean> mFinishedTransitionCallback; - private @Nullable ToolbarAlphaInOverviewObserver mToolbarAlphaInOverviewObserver; - StartSurfaceToolbarMediator(Context context, PropertyModel model, Callback<IPHCommandBuilder> showIdentityIPHCallback, boolean hideIncognitoSwitchWhenNoTabs, MenuButtonCoordinator menuButtonCoordinator, @@ -112,8 +107,7 @@ BooleanSupplier isIncognitoModeEnabledSupplier, Callback<LoadUrlParams> logoClickedCallback, boolean isRefactorEnabled, boolean shouldFetchDoodle, boolean shouldCreateLogoInToolbar, - Callback<Boolean> finishedTransitionCallback, - ToolbarAlphaInOverviewObserver toolbarAlphaInOverviewObserver) { + Callback<Boolean> finishedTransitionCallback) { mPropertyModel = model; mStartSurfaceState = StartSurfaceState.NOT_SHOWN; mShowIdentityIPHCallback = showIdentityIPHCallback; @@ -131,7 +125,6 @@ mShouldCreateLogoInToolbar = shouldCreateLogoInToolbar; mIsRefactorEnabled = isRefactorEnabled; mFinishedTransitionCallback = finishedTransitionCallback; - mToolbarAlphaInOverviewObserver = toolbarAlphaInOverviewObserver; mContext = context; mShouldShowTabSwitcherButtonOnHomepage = shouldShowTabSwitcherButtonOnHomepage; @@ -177,9 +170,6 @@ mCallbackController.destroy(); mCallbackController = null; } - if (mToolbarAlphaInOverviewObserver != null) { - mToolbarAlphaInOverviewObserver = null; - } mIdentityDiscController.removeObserver(this); } @@ -382,17 +372,6 @@ finishAlphaAnimator(shouldShowStartSurfaceToolbar); } }); - // Notify the observer that the toolbar alpha value is changed and pass the rendering - // toolbar alpha value to the observer. - if (mToolbarAlphaInOverviewObserver != null) { - mAlphaAnimator.addUpdateListener((animation) -> { - Object alphaValue = animation.getAnimatedValue(); - if (alphaValue != null && alphaValue instanceof Float) { - mToolbarAlphaInOverviewObserver.onToolbarAlphaInOverviewChanged( - (float) alphaValue); - } - }); - } mAlphaAnimator.start(); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinator.java index ba35831..341a0232 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinator.java
@@ -46,8 +46,6 @@ private TabSwitcherModeTopToolbar mTabSwitcherToolbar; private TabSwitcherModeTopToolbar mTabSwitcherFullscreenToolbar; - private ToolbarColorObserverManager mToolbarColorObserverManager; - @Nullable private IncognitoTabModelObserver mIncognitoTabModelObserver; @@ -60,8 +58,7 @@ TabSwitcherModeTTCoordinator(ViewStub tabSwitcherToolbarStub, ViewStub tabSwitcherFullscreenToolbarStub, MenuButtonCoordinator menuButtonCoordinator, boolean isGridTabSwitcherEnabled, boolean isTabletGtsPolishEnabled, - boolean isTabToGtsAnimationEnabled, BooleanSupplier isIncognitoModeEnabledSupplier, - ToolbarColorObserverManager toolbarColorObserverManager) { + boolean isTabToGtsAnimationEnabled, BooleanSupplier isIncognitoModeEnabledSupplier) { mTabSwitcherToolbarStub = tabSwitcherToolbarStub; mTabSwitcherFullscreenToolbarStub = tabSwitcherFullscreenToolbarStub; mMenuButtonCoordinator = menuButtonCoordinator; @@ -71,7 +68,6 @@ mIsIncognitoModeEnabledSupplier = isIncognitoModeEnabledSupplier; mTopToolbarInteractabilityManager = new TopToolbarInteractabilityManager(enabled -> setNewTabEnabled(enabled)); - mToolbarColorObserverManager = toolbarColorObserverManager; } /** @@ -239,8 +235,7 @@ */ private void initializeToolbar(TabSwitcherModeTopToolbar toolbar, boolean isFullscreenToolbar) { toolbar.initialize(mIsGridTabSwitcherEnabled, isFullscreenToolbar, - mIsTabToGtsAnimationEnabled, mIsIncognitoModeEnabledSupplier, - mToolbarColorObserverManager); + mIsTabToGtsAnimationEnabled, mIsIncognitoModeEnabledSupplier); mMenuButtonCoordinator.setMenuButton(toolbar.findViewById(R.id.menu_button_wrapper)); // It's expected that these properties are set by the time the tab switcher is entered.
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java index a15dbb2..45d5117d 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java
@@ -27,7 +27,6 @@ import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.menu_button.MenuButton; -import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.ToolbarAlphaInOverviewObserver; import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.widget.animation.CancelAwareAnimatorListener; @@ -72,8 +71,6 @@ private boolean mIsFullscreenToolbar; private boolean mShowZoomingAnimation; - private @Nullable ToolbarAlphaInOverviewObserver mToolbarAlphaInOverviewObserver; - public TabSwitcherModeTopToolbar(Context context, AttributeSet attrs) { super(context, attrs); } @@ -97,13 +94,11 @@ } void initialize(boolean isGridTabSwitcherEnabled, boolean isFullscreenToolbar, - boolean isTabToGtsAnimationEnabled, BooleanSupplier isIncognitoModeEnabledSupplier, - ToolbarColorObserverManager toolbarColorObserverManager) { + boolean isTabToGtsAnimationEnabled, BooleanSupplier isIncognitoModeEnabledSupplier) { mIsGridTabSwitcherEnabled = isGridTabSwitcherEnabled; mIsFullscreenToolbar = isFullscreenToolbar; mShowZoomingAnimation = isGridTabSwitcherEnabled && isTabToGtsAnimationEnabled; mIsIncognitoModeEnabledSupplier = isIncognitoModeEnabledSupplier; - mToolbarAlphaInOverviewObserver = toolbarColorObserverManager; mNewTabImageButton.setGridTabSwitcherEnabled(isGridTabSwitcherEnabled); mNewTabImageButton.setStartSurfaceEnabled(false); @@ -140,9 +135,6 @@ mIncognitoToggleTabLayout.destroy(); mIncognitoToggleTabLayout = null; } - if (mToolbarAlphaInOverviewObserver != null) { - mToolbarAlphaInOverviewObserver = null; - } } /** @@ -195,17 +187,7 @@ mVisiblityAnimator = null; } }); - // Notify the observer that the toolbar alpha value is changed and pass the rendering - // toolbar alpha value to the observer. - if (mToolbarAlphaInOverviewObserver != null) { - mVisiblityAnimator.addUpdateListener((animation) -> { - Object alphaValue = animation.getAnimatedValue(); - if (alphaValue != null && alphaValue instanceof Float) { - mToolbarAlphaInOverviewObserver.onToolbarAlphaInOverviewChanged( - (float) alphaValue); - } - }); - } + mVisiblityAnimator.start(); if (DeviceClassManager.enableAccessibilityLayout(getContext())) mVisiblityAnimator.end();
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarColorObserverManager.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarColorObserverManager.java deleted file mode 100644 index 679e5da..0000000 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarColorObserverManager.java +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.toolbar.top; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; -import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.ToolbarAlphaInOverviewObserver; -import org.chromium.chrome.browser.toolbar.top.TopToolbarCoordinator.ToolbarColorObserver; -import org.chromium.components.browser_ui.styles.ChromeColors; -import org.chromium.ui.util.ColorUtils; - -/** - * A class to receive toolbar color change updates from toolbar components and send the - * rendering toolbar color to the ToolbarColorObserver. - */ -class ToolbarColorObserverManager implements ToolbarAlphaInOverviewObserver, ToolbarColorObserver { - private @Nullable ToolbarColorObserver mToolbarColorObserver; - - private Context mContext; - private IncognitoStateProvider mIncognitoStateProvider; - private float mToolbarAlphaValue; - private int mToolbarColor; - - ToolbarColorObserverManager(Context context, ToolbarLayout toolbarLayout) { - mContext = context; - mToolbarAlphaValue = 0; - // Initialize mToolbarColor for first load of website. - if (toolbarLayout instanceof ToolbarPhone) { - mToolbarColor = ((ToolbarPhone) toolbarLayout).getToolbarBackgroundColor(); - } - } - - /** - * @param provider The provider used to determine incognito state. - */ - void setIncognitoStateProvider(IncognitoStateProvider provider) { - mIncognitoStateProvider = provider; - } - - /** - * Set Toolbar Color Observer for the toolbar color changes. - * @param toolbarColorObserver The observer to listen to toolbar color change. - */ - void setToolbarColorObserver(@NonNull ToolbarColorObserver toolbarColorObserver) { - mToolbarColorObserver = toolbarColorObserver; - } - - // TopToolbarCoordinator.ToolbarColorObserver implementation. - @Override - public void onToolbarColorChanged(int color) { - mToolbarColor = color; - notifyToolbarColorChanged(); - } - - // TopToolbarCoordinator.ToolbarAlphaInOverviewObserver implementation. - @Override - public void onToolbarAlphaInOverviewChanged(float fraction) { - mToolbarAlphaValue = fraction; - notifyToolbarColorChanged(); - } - - /** - * Notify the observer that the toolbar color is changed based on alpha value and toolbar color, - * and send the rendering toolbar color to the observer. - */ - private void notifyToolbarColorChanged() { - if (mToolbarColorObserver != null && mIncognitoStateProvider != null) { - boolean isIncognito = mIncognitoStateProvider.isIncognitoSelected(); - int overviewColor = ChromeColors.getPrimaryBackgroundColor(mContext, isIncognito); - int toolbarRenderingColor = ColorUtils.getColorWithOverlay( - mToolbarColor, overviewColor, mToolbarAlphaValue); - mToolbarColorObserver.onToolbarColorChanged(toolbarRenderingColor); - } - } -} \ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 3458d6a2..1e0e2d6 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -2722,7 +2722,8 @@ /** * Returns the toolbar's background color. */ - public int getToolbarBackgroundColor() { + @VisibleForTesting + public int getToolbarBackgroundColorForTesting(Activity activity) { return mToolbarBackground.getColor(); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index b36e6bd..0da911c 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -79,14 +79,6 @@ void onToolbarColorChanged(int color); } - /** - * Observes toolbar alpha change during overview mode fading animation. - */ - public interface ToolbarAlphaInOverviewObserver { - /** @param fraction The toolbar alpha value. */ - void onToolbarAlphaInOverviewChanged(float fraction); - } - public static final int TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS = 200; public static final int TAB_SWITCHER_MODE_GTS_ANIMATION_DURATION_MS = 150; @@ -116,8 +108,6 @@ private TopToolbarOverlayCoordinator mOverlayCoordinator; private boolean mStartSurfaceToolbarVisible; - private ToolbarColorObserverManager mToolbarColorObserverManager; - /** * Creates a new {@link TopToolbarCoordinator}. * @param controlContainer The {@link ToolbarControlContainer} for the containing activity. @@ -193,9 +183,6 @@ mResourceManagerSupplier = resourceManagerSupplier; mTabModelSelectorSupplier = tabModelSelectorSupplier; mIsStartSurfaceRefactorEnabled = isStartSurfaceRefactorEnabled; - mToolbarColorObserverManager = - new ToolbarColorObserverManager(mToolbarLayout.getContext(), mToolbarLayout); - mToolbarLayout.setToolbarColorObserver(mToolbarColorObserverManager); if (mToolbarLayout instanceof ToolbarPhone && isStartSurfaceEnabled) { mStartSurfaceToolbarCoordinator = new StartSurfaceToolbarCoordinator(toolbarStub, @@ -204,13 +191,12 @@ isGridTabSwitcherEnabled, isTabToGtsAnimationEnabled, isTabGroupsAndroidContinuationEnabled, isIncognitoModeEnabledSupplier, startSurfaceLogoClickedCallback, mIsStartSurfaceRefactorEnabled, - shouldCreateLogoInStartToolbar, this::onStartSurfaceToolbarTransitionFinished, - mToolbarColorObserverManager); + shouldCreateLogoInStartToolbar, this::onStartSurfaceToolbarTransitionFinished); } else if (mToolbarLayout instanceof ToolbarPhone || isTabletGridTabSwitcherEnabled()) { mTabSwitcherModeCoordinator = new TabSwitcherModeTTCoordinator(toolbarStub, fullscreenToolbarStub, overviewModeMenuButtonCoordinator, isGridTabSwitcherEnabled, isTabletGtsPolishEnabled, isTabToGtsAnimationEnabled, - isIncognitoModeEnabledSupplier, mToolbarColorObserverManager); + isIncognitoModeEnabledSupplier); } controlContainer.setPostInitializationDependencies(this, initializeWithIncognitoColors, constraintsSupplier, toolbarDataProvider::getTab, compositorInMotionSupplier, @@ -330,7 +316,7 @@ * @param toolbarColorObserver The observer that observes toolbar color change. */ public void setToolbarColorObserver(@NonNull ToolbarColorObserver toolbarColorObserver) { - mToolbarColorObserverManager.setToolbarColorObserver(toolbarColorObserver); + mToolbarLayout.setToolbarColorObserver(toolbarColorObserver); } /** @@ -633,7 +619,6 @@ } else if (mStartSurfaceToolbarCoordinator != null) { mStartSurfaceToolbarCoordinator.setIncognitoStateProvider(provider); } - mToolbarColorObserverManager.setIncognitoStateProvider(provider); } /**
diff --git a/chrome/browser/ui/ash/assistant/assistant_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_browsertest.cc index 58dfce1..c47763f 100644 --- a/chrome/browser/ui/ash/assistant/assistant_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_browsertest.cc
@@ -54,8 +54,13 @@ public testing::WithParamInterface<bool> { public: AssistantBrowserTest() { - if (GetParam()) - feature_list_.InitAndEnableFeature(features::kEnableLibAssistantDlc); + if (GetParam()) { + feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEnableLibAssistantDlc}, + /*disabled_features=*/{features::kEnableLibAssistantSandbox}); + } else { + feature_list_.InitAndDisableFeature(features::kEnableLibAssistantSandbox); + } // Do not log to file in test. Otherwise multiple tests may create/delete // the log file at the same time. See http://crbug.com/1307868.
diff --git a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc index 3e18ed6a..d9a9c22c 100644 --- a/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_timers_browsertest.cc
@@ -188,11 +188,17 @@ // AssistantTimersBrowserTest -------------------------------------------------- -class AssistantTimersBrowserTest : public MixinBasedInProcessBrowserTest { +class AssistantTimersBrowserTest : public MixinBasedInProcessBrowserTest, + public testing::WithParamInterface<bool> { public: AssistantTimersBrowserTest() { - // TODO(b/190633242): enable sandbox in browser tests. - feature_list_.InitAndDisableFeature(features::kEnableLibAssistantSandbox); + if (GetParam()) { + feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kEnableLibAssistantDlc}, + /*disabled_features=*/{features::kEnableLibAssistantSandbox}); + } else { + feature_list_.InitAndDisableFeature(features::kEnableLibAssistantSandbox); + } // Do not log to file in test. Otherwise multiple tests may create/delete // the log file at the same time. See http://crbug.com/1307868. @@ -226,7 +232,7 @@ // Timer notifications should be dismissed when disabling Assistant in settings. // Flaky. See https://crbug.com/1196564. -IN_PROC_BROWSER_TEST_F( +IN_PROC_BROWSER_TEST_P( AssistantTimersBrowserTest, DISABLED_ShouldDismissTimerNotificationsWhenDisablingAssistant) { tester()->StartAssistantAndWaitForReady(); @@ -257,7 +263,7 @@ // Pressing the "STOP" action button in a timer notification should result in // the timer being removed. // Flaky. See https://crbug.com/1196564. -IN_PROC_BROWSER_TEST_F(AssistantTimersBrowserTest, +IN_PROC_BROWSER_TEST_P(AssistantTimersBrowserTest, DISABLED_ShouldRemoveTimerWhenStoppingViaNotification) { tester()->StartAssistantAndWaitForReady(); @@ -298,7 +304,7 @@ } // Verifies that timer notifications are ticked at regular intervals. -IN_PROC_BROWSER_TEST_F(AssistantTimersBrowserTest, +IN_PROC_BROWSER_TEST_P(AssistantTimersBrowserTest, ShouldTickNotificationsAtRegularIntervals) { // Observe notifications. MockMessageCenterObserver mock; @@ -388,4 +394,8 @@ notification_update_run_loop.Run(); } +INSTANTIATE_TEST_SUITE_P(/* no label */, + AssistantTimersBrowserTest, + /*values=*/testing::Bool()); + } // namespace ash::assistant
diff --git a/chrome/browser/ui/extensions/settings_overridden_params_providers_unittest.cc b/chrome/browser/ui/extensions/settings_overridden_params_providers_unittest.cc index 9aab079..4263f04 100644 --- a/chrome/browser/ui/extensions/settings_overridden_params_providers_unittest.cc +++ b/chrome/browser/ui/extensions/settings_overridden_params_providers_unittest.cc
@@ -43,14 +43,13 @@ // Adds a new extension that overrides the NTP. const extensions::Extension* AddExtensionControllingNewTab( const char* name = "ntp override") { - base::Value chrome_url_overrides = base::Value::FromUniquePtrValue( - extensions::DictionaryBuilder().Set("newtab", "newtab.html").Build()); + base::Value::Dict chrome_url_overrides = + extensions::DictionaryBuilder().Set("newtab", "newtab.html").Build(); scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder(name) .SetLocation(extensions::mojom::ManifestLocation::kInternal) - .SetManifestKey( - "chrome_url_overrides", - base::Value::ToUniquePtrValue(std::move(chrome_url_overrides))) + .SetManifestKey("chrome_url_overrides", + std::move(chrome_url_overrides)) .Build(); service()->AddExtension(extension.get());
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc index 9722007..cdffe58e 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc
@@ -39,7 +39,7 @@ protected: AppInfoPermissionsPanelTest() {} - std::unique_ptr<base::DictionaryValue> ValidAppManifest() { + base::Value::Dict ValidAppManifest() { return extensions::DictionaryBuilder() .Set("name", "Test App Name") .Set("version", "2.0")
diff --git a/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc b/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc index e3e447a..ac6c7d2 100644 --- a/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc +++ b/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc
@@ -26,13 +26,9 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/color/chrome_color_id.h" -#include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" -#include "components/lens/lens_entrypoints.h" -#include "components/lens/lens_features.h" -#include "components/lens/lens_rendering_environment.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/download_request_utils.h" #include "content/public/browser/web_contents.h" @@ -50,8 +46,6 @@ #include "ui/views/layout/table_layout_view.h" #include "ui/views/view.h" -using content::WebContents; - namespace { // Rendered image size, pixels. @@ -81,14 +75,6 @@ ->IsImageEditorAvailable(); } -bool IsSearchImageEnabled() { -#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) - return lens::features::IsLensInScreenshotSharingEnabled(); -#else - return false; -#endif -} - ScreenshotCapturedBubble::ScreenshotCapturedBubble( views::View* anchor_view, content::WebContents* web_contents, @@ -184,15 +170,6 @@ IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_EDIT_BUTTON_LABEL)) .Build(); - auto search_image_button = - views::Builder<views::MdTextButton>() - .SetCallback(base::BindRepeating( - &ScreenshotCapturedBubble::SearchImageButtonPressed, - weak_factory_.GetWeakPtr())) - .SetText(l10n_util::GetStringUTF16( - IDS_BROWSER_SHARING_SCREENSHOT_DIALOG_SEARCH_IMAGE_BUTTON_LABEL)) - .Build(); - auto download_button = views::Builder<views::MdTextButton>() .SetCallback(base::BindRepeating( @@ -205,34 +182,19 @@ auto download_row = views::Builder<views::TableLayoutView>(); if (IsEditorInstalled()) { - download_row.AddColumn( - /* h_align */ views::LayoutAlignment::kStart, - /* v_align */ views::LayoutAlignment::kCenter, - /* horizontal_resize */ 1.0, - /* size_type */ views::TableLayout::ColumnSize::kUsePreferred, - /* fixed_width */ 0, /* min_width */ 0); - } - - if (IsSearchImageEnabled()) { - download_row.AddColumn( - /* h_align */ views::LayoutAlignment::kStart, - /* v_align */ views::LayoutAlignment::kCenter, - /* horizontal_resize */ 1.0, - /* size_type */ views::TableLayout::ColumnSize::kUsePreferred, - /* fixed_width */ 0, /* min_width */ 0); - } - - if (IsEditorInstalled() || IsSearchImageEnabled()) { - const int kPaddingEditSearchDownloadButtonPx = - kImageWidthPx - - (IsEditorInstalled() ? edit_button->CalculatePreferredSize().width() - : 0) - - (IsSearchImageEnabled() - ? search_image_button->CalculatePreferredSize().width() - : 0) - + const int kPaddingEditDownloadButtonPx = + kImageWidthPx - edit_button->CalculatePreferredSize().width() - download_button->CalculatePreferredSize().width(); - download_row.AddPaddingColumn(views::TableLayout::kFixedSize, - kPaddingEditSearchDownloadButtonPx); + + download_row + .AddColumn( + /* h_align */ views::LayoutAlignment::kStart, + /* v_align */ views::LayoutAlignment::kCenter, + /* horizontal_resize */ 1.0, + /* size_type */ views::TableLayout::ColumnSize::kUsePreferred, + /* fixed_width */ 0, /* min_width */ 0) + .AddPaddingColumn(views::TableLayout::kFixedSize, + kPaddingEditDownloadButtonPx); } // Column for download button @@ -246,11 +208,6 @@ views::Builder<views::MdTextButton>(std::move(edit_button)) .CopyAddressTo(&edit_button_)); } - if (IsSearchImageEnabled()) { - download_row.AddChild( - views::Builder<views::MdTextButton>(std::move(search_image_button)) - .CopyAddressTo(&search_image_button_)); - } download_row.AddChild( views::Builder<views::MdTextButton>(std::move(download_button)) .CopyAddressTo(&download_button_)); @@ -335,26 +292,6 @@ weak_factory_.GetWeakPtr())); } -void ScreenshotCapturedBubble::SearchImageButtonPressed() { - // If EnablePersistentBubble() is true, we do not close the screenshot bubble - set_close_on_deactivate(!lens::features::EnablePersistentBubble()); - - CoreTabHelper::FromWebContents(web_contents_.get()) - ->SearchWithLens(image_, GetImageSize(), - lens::EntryPoint::CHROME_SCREENSHOT_SEARCH, - /* is_region_search_request= */ false, - /* is_side_panel_enabled_for_feature= */ - lens::features::UseSidePanelForScreenshotSharing()); - - // Need to manually close the screenshot bubble if side panel is enabled - if (lens::features::UseSidePanelForScreenshotSharing() && - !lens::features::EnablePersistentBubble()) { - CloseBubble(); - } - - set_close_on_deactivate(true); -} - void ScreenshotCapturedBubble::NavigateToImageEditor( const base::FilePath& screenshot_file_path) { auto screenshot_data =
diff --git a/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.h b/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.h index 1730914..f3659129 100644 --- a/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.h +++ b/chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.h
@@ -69,8 +69,6 @@ void EditButtonPressed(); - void SearchImageButtonPressed(); - gfx::Size GetImageSize(); // Requests navigation to the image editor page. @@ -92,7 +90,6 @@ views::ImageView* image_view_ = nullptr; views::MdTextButton* download_button_ = nullptr; views::LabelButton* edit_button_ = nullptr; - views::LabelButton* search_image_button_ = nullptr; base::WeakPtrFactory<ScreenshotCapturedBubble> weak_factory_{this}; };
diff --git a/chrome/browser/ui/webui/ash/drive_internals_ui.cc b/chrome/browser/ui/webui/ash/drive_internals_ui.cc index 9ca3542..35605d00 100644 --- a/chrome/browser/ui/webui/ash/drive_internals_ui.cc +++ b/chrome/browser/ui/webui/ash/drive_internals_ui.cc
@@ -623,23 +623,18 @@ void OnSetupProgress( const drivefs::pinning::SetupProgress& progress) override { using drivefs::pinning::HumanReadableSize; - VLOG(1) << "Stage = " << progress.stage; - VLOG(1) << "Error = " << progress.error; - VLOG(1) << "Free space = " - << HumanReadableSize(progress.available_disk_space); - VLOG(1) << "Required space = " - << HumanReadableSize(progress.required_disk_space); - VLOG(1) << "Pinned space = " - << HumanReadableSize(progress.pinned_disk_space); base::Value::Dict setup_progress; setup_progress.Set("stage", ToString(progress.stage)); setup_progress.Set("setupError", ToString(progress.error)); - setup_progress.Set("availableDiskSpace", - ToString(progress.available_disk_space)); - setup_progress.Set("requiredDiskSpace", - ToString(progress.required_disk_space)); - setup_progress.Set("pinnedDiskSpace", ToString(progress.pinned_disk_space)); + setup_progress.Set( + "availableDiskSpace", + ToString(HumanReadableSize(progress.available_disk_space))); + setup_progress.Set( + "requiredDiskSpace", + ToString(HumanReadableSize(progress.required_disk_space))); + setup_progress.Set("pinnedDiskSpace", + ToString(HumanReadableSize(progress.pinned_disk_space))); MaybeCallJavascript("onBulkPinningProgress", base::Value(std::move(setup_progress))); }
diff --git a/chrome/browser/ui/webui/settings/ash/device_storage_handler_unittest.cc b/chrome/browser/ui/webui/settings/ash/device_storage_handler_unittest.cc index 17d9879f..b27fb12e 100644 --- a/chrome/browser/ui/webui/settings/ash/device_storage_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/device_storage_handler_unittest.cc
@@ -42,16 +42,6 @@ namespace { -class TestStorageHandler : public StorageHandler { - public: - explicit TestStorageHandler(Profile* profile, - content::WebUIDataSource* html_source) - : StorageHandler(profile, html_source) {} - - // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it. - using StorageHandler::set_web_ui; -}; - class MockNewWindowDelegate : public testing::NiceMock<TestNewWindowDelegate> { public: // TestNewWindowDelegate: @@ -94,7 +84,7 @@ content::WebUIDataSource* html_source = content::WebUIDataSource::CreateAndAdd(profile_, chrome::kChromeUIOSSettingsHost); - auto handler = std::make_unique<TestStorageHandler>(profile_, html_source); + auto handler = std::make_unique<StorageHandler>(profile_, html_source); handler_ = handler.get(); web_ui_ = std::make_unique<content::TestWebUI>(); web_ui_->AddMessageHandler(std::move(handler)); @@ -214,7 +204,7 @@ ASSERT_EQ(expected_size, stat.st_size); } - TestStorageHandler* handler_; + StorageHandler* handler_; std::unique_ptr<content::TestWebUI> web_ui_; content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfileManager> profile_manager_;
diff --git a/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.cc b/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.cc index abcd60a..df71a64 100644 --- a/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.cc +++ b/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.cc
@@ -7,11 +7,13 @@ #include <utility> #include "ash/public/cpp/message_center_ash.h" +#include "ash/public/cpp/new_window_delegate.h" #include "base/logging.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits.h" +#include "chrome/common/url_constants.h" #include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/features.h" #include "components/services/app_service/public/cpp/permission.h" @@ -105,6 +107,13 @@ app_service_proxy_->SetPermission(app_id, std::move(permission)); } +void AppNotificationHandler::OpenBrowserNotificationSettings() { + ash::NewWindowDelegate::GetPrimary()->OpenUrl( + GURL(chrome::kAppNotificationsBrowserSettingsURL), + ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, + ash::NewWindowDelegate::Disposition::kSwitchToTab); +} + void AppNotificationHandler::GetApps(GetAppsCallback callback) { std::move(callback).Run(GetAppList()); }
diff --git a/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h b/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h index 1f7a9013..885b1ee 100644 --- a/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h +++ b/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h
@@ -44,6 +44,7 @@ apps::PermissionPtr permission) override; void GetApps(GetAppsCallback callback) override; void GetQuietMode(GetQuietModeCallback callback) override; + void OpenBrowserNotificationSettings() override; // apps::AppRegistryCache::Observer: void OnAppUpdate(const apps::AppUpdate& update) override;
diff --git a/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler_unittest.cc b/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler_unittest.cc index 511d744f..91722b4 100644 --- a/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler_unittest.cc
@@ -9,15 +9,18 @@ #include <vector> #include "ash/public/cpp/message_center_ash.h" +#include "ash/public/cpp/test/test_new_window_delegate.h" #include "base/logging.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom.h" +#include "chrome/common/url_constants.h" #include "chrome/test/base/testing_profile.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" #include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/permission.h" #include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/variant.h" @@ -87,6 +90,15 @@ this}; }; +class MockNewWindowDelegate : public testing::NiceMock<TestNewWindowDelegate> { + public: + // TestNewWindowDelegate: + MOCK_METHOD(void, + OpenUrl, + (const GURL& url, OpenUrlFrom from, Disposition disposition), + (override)); +}; + } // namespace class AppNotificationHandlerTest : public testing::Test { @@ -105,21 +117,34 @@ observer_ = std::make_unique<AppNotificationHandlerTestObserver>(); handler_->AddObserver(observer_->GenerateRemote()); + + auto instance = std::make_unique<MockNewWindowDelegate>(); + auto primary = std::make_unique<MockNewWindowDelegate>(); + new_window_delegate_primary_ = primary.get(); + new_window_provider_ = std::make_unique<TestNewWindowDelegateProvider>( + std::move(instance), std::move(primary)); } void TearDown() override { + new_window_provider_.reset(); handler_.reset(); app_service_proxy_.reset(); MessageCenterAsh::SetForTesting(nullptr); } protected: + MockNewWindowDelegate* new_window_delegate_primary_; + AppNotificationHandlerTestObserver* observer() { return observer_.get(); } void SetQuietModeState(bool quiet_mode_enabled) { handler_->SetQuietMode(quiet_mode_enabled); } + void OpenBrowserNotificationSettings() { + handler_->OpenBrowserNotificationSettings(); + } + void CreateAndStoreFakeApp(std::string fake_id, apps::AppType app_type, apps::PermissionType permission_type, @@ -164,6 +189,7 @@ std::unique_ptr<apps::AppServiceProxy> app_service_proxy_; FakeMessageCenterAsh message_center_ash_; std::unique_ptr<AppNotificationHandlerTestObserver> observer_; + std::unique_ptr<TestNewWindowDelegateProvider> new_window_provider_; }; // Tests for update of in_quiet_mode_ variable by MessageCenterAsh observer @@ -261,4 +287,13 @@ ->notification_permission->value->value)); } +TEST_F(AppNotificationHandlerTest, TestOpenBrowserNotificationSettings) { + EXPECT_CALL(*new_window_delegate_primary_, + OpenUrl(GURL(chrome::kAppNotificationsBrowserSettingsURL), + ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, + ash::NewWindowDelegate::Disposition::kSwitchToTab)); + base::Value::List empty_args; + OpenBrowserNotificationSettings(); +} + } // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom b/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom index a5cc55f..308caf7 100644 --- a/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom +++ b/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom
@@ -57,6 +57,9 @@ // Get the Quiet Mode state. GetQuietMode() => (bool enabled); + + // Request the browser to open its notification settings. + OpenBrowserNotificationSettings(); }; // Frontend interface. @@ -68,4 +71,4 @@ OnNotificationAppChanged(App app); // Notifies client when the DoNotDisturb (QuietMode) state changes. OnQuietModeChanged(bool enabled); -}; \ No newline at end of file +};
diff --git a/chrome/browser/ui/webui/settings/ash/search_engines_handler_unittest.cc b/chrome/browser/ui/webui/settings/ash/search_engines_handler_unittest.cc new file mode 100644 index 0000000..14ca9b0c --- /dev/null +++ b/chrome/browser/ui/webui/settings/ash/search_engines_handler_unittest.cc
@@ -0,0 +1,92 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/search_engines_handler.h" + +#include "ash/public/cpp/test/test_new_window_delegate.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash::settings { + +namespace { + +class MockNewWindowDelegate : public testing::NiceMock<TestNewWindowDelegate> { + public: + // TestNewWindowDelegate: + MOCK_METHOD(void, + OpenUrl, + (const GURL& url, OpenUrlFrom from, Disposition disposition), + (override)); +}; + +class SearchEnginesHandlerTest : public testing::Test { + public: + SearchEnginesHandlerTest() = default; + SearchEnginesHandlerTest(const SearchEnginesHandlerTest&) = delete; + SearchEnginesHandlerTest& operator=(const SearchEnginesHandlerTest&) = delete; + ~SearchEnginesHandlerTest() override = default; + + void SetUp() override { + // Initialize profile. + profile_manager_ = std::make_unique<TestingProfileManager>( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(profile_manager_->SetUp()); + Profile* profile = profile_manager_->CreateTestingProfile( + chrome::kInitialProfile, + {{TemplateURLServiceFactory::GetInstance(), + base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor)}}); + + // Initialize handler and webui. + auto handler = std::make_unique<::settings::SearchEnginesHandler>(profile); + handler_ = handler.get(); + web_ui_ = std::make_unique<content::TestWebUI>(); + web_ui_->AddMessageHandler(std::move(handler)); + handler_->AllowJavascriptForTesting(); + + // Initialize NewWindowDelegate things. + auto instance = std::make_unique<MockNewWindowDelegate>(); + auto primary = std::make_unique<MockNewWindowDelegate>(); + new_window_delegate_primary_ = primary.get(); + new_window_provider_ = std::make_unique<TestNewWindowDelegateProvider>( + std::move(instance), std::move(primary)); + } + + void TearDown() override { + new_window_provider_.reset(); + web_ui_.reset(); + } + + protected: + std::unique_ptr<content::TestWebUI> web_ui_; + MockNewWindowDelegate* new_window_delegate_primary_; + + private: + content::BrowserTaskEnvironment task_environment_; + ::settings::SearchEnginesHandler* handler_; + std::unique_ptr<TestingProfileManager> profile_manager_; + std::unique_ptr<TestNewWindowDelegateProvider> new_window_provider_; +}; + +TEST_F(SearchEnginesHandlerTest, OpenBrowserSearchSettings) { + EXPECT_CALL( + *new_window_delegate_primary_, + OpenUrl( + GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kSearchSubPage), + ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, + ash::NewWindowDelegate::Disposition::kSwitchToTab)); + base::Value::List empty_args; + web_ui_->HandleReceivedMessage("openBrowserSearchSettings", empty_args); +} + +} // namespace + +} // namespace ash::settings
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc index 7f7577a..6e5b436 100644 --- a/chrome/browser/ui/webui/settings/search_engines_handler.cc +++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ui/search_engines/template_url_table_model.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h" #include "components/search_engines/template_url.h" @@ -31,6 +32,10 @@ #include "extensions/browser/management_policy.h" #include "extensions/common/extension.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/public/cpp/new_window_delegate.h" +#endif + namespace { // The following strings need to match with the IDs of the text input elements // at settings/search_engines_page/search_engine_edit_dialog.html. @@ -92,6 +97,13 @@ base::BindRepeating( &SearchEnginesHandler::HandleSearchEngineEditCompleted, base::Unretained(this))); +#if BUILDFLAG(IS_CHROMEOS_ASH) + web_ui()->RegisterMessageCallback( + "openBrowserSearchSettings", + base::BindRepeating( + &SearchEnginesHandler::HandleOpenBrowserSearchSettings, + base::Unretained(this))); +#endif } void SearchEnginesHandler::OnJavascriptAllowed() { @@ -380,4 +392,14 @@ } } +#if BUILDFLAG(IS_CHROMEOS_ASH) +void SearchEnginesHandler::HandleOpenBrowserSearchSettings( + const base::Value::List& args) { + ash::NewWindowDelegate::GetPrimary()->OpenUrl( + GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kSearchSubPage), + ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, + ash::NewWindowDelegate::Disposition::kSwitchToTab); +} +#endif + } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.h b/chrome/browser/ui/webui/settings/search_engines_handler.h index 155ba21..9f389106 100644 --- a/chrome/browser/ui/webui/settings/search_engines_handler.h +++ b/chrome/browser/ui/webui/settings/search_engines_handler.h
@@ -86,6 +86,11 @@ // Called from WebUI. void HandleSearchEngineEditCompleted(const base::Value::List& args); +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Request the browser to open its search settings. + void HandleOpenBrowserSearchSettings(const base::Value::List& args); +#endif + // Returns a dictionary to pass to WebUI representing the given search engine. base::Value::Dict CreateDictionaryForEngine(size_t index, bool is_default);
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom index e5eec242..07033e0e 100644 --- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom +++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks.mojom
@@ -25,6 +25,22 @@ // Bookmarks the current active tab in the given folder. BookmarkCurrentTabInFolder(int64 folder_id); + // Opens the bookmark specified by node_id in a new background tab, using the + // same logic as the native bookmarks context menu. + ExecuteOpenInNewTabCommand(int64 node_id, ActionSource source); + + // Opens the bookmark specified by node_id in a new window, using the same + // logic as the native bookmarks context menu. + ExecuteOpenInNewWindowCommand(int64 node_id, ActionSource source); + + // Opens the bookmark specified by node_id in a new incognito window, using + // the same logic as the native bookmarks context menu. + ExecuteOpenInIncognitoWindowCommand(int64 node_id, ActionSource source); + + // Deletes bookmark specified by node_id, using the same logic as the native + // bookmarks context menu. + ExecuteDeleteCommand(int64 node_id, ActionSource source); + // Opens the bookmark specified by node_id. Passes the parent folder // depth for metrics collection and the action source to identify // from which surface this request is made.
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.cc b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.cc index 23c328e8..1a414a9 100644 --- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.cc
@@ -3,12 +3,10 @@ // found in the LICENSE file. #include "chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.h" -#include <string> #include "base/memory/ptr_util.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" -#include "base/strings/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/commerce/shopping_service_factory.h" @@ -135,6 +133,27 @@ shopping_list_controller_; }; +std::unique_ptr<BookmarkContextMenu> ContextMenuFromNode( + int64_t node_id, + base::WeakPtr<ui::MojoBubbleWebUIController::Embedder> embedder, + side_panel::mojom::ActionSource source) { + Browser* browser = chrome::FindLastActive(); + if (!browser) { + return nullptr; + } + + bookmarks::BookmarkModel* bookmark_model = + BookmarkModelFactory::GetForBrowserContext(browser->profile()); + const bookmarks::BookmarkNode* bookmark = + bookmarks::GetBookmarkNodeByID(bookmark_model, node_id); + if (!bookmark) { + return nullptr; + } + + return std::make_unique<BookmarkContextMenu>(browser, embedder, bookmark, + source); +} + } // namespace BookmarksPageHandler::BookmarksPageHandler( @@ -157,6 +176,54 @@ chrome::BookmarkCurrentTabInFolder(browser, folder_id); } +void BookmarksPageHandler::ExecuteOpenInNewTabCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) { + auto embedder = + bookmarks_ui_ ? bookmarks_ui_->embedder() : reading_list_ui_->embedder(); + std::unique_ptr<BookmarkContextMenu> contextMenu = + ContextMenuFromNode(node_id, embedder, source); + if (contextMenu) { + contextMenu->ExecuteCommand(IDC_BOOKMARK_BAR_OPEN_ALL, 0); + } +} + +void BookmarksPageHandler::ExecuteOpenInNewWindowCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) { + auto embedder = + bookmarks_ui_ ? bookmarks_ui_->embedder() : reading_list_ui_->embedder(); + std::unique_ptr<BookmarkContextMenu> contextMenu = + ContextMenuFromNode(node_id, embedder, source); + if (contextMenu) { + contextMenu->ExecuteCommand(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW, 0); + } +} + +void BookmarksPageHandler::ExecuteOpenInIncognitoWindowCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) { + auto embedder = + bookmarks_ui_ ? bookmarks_ui_->embedder() : reading_list_ui_->embedder(); + std::unique_ptr<BookmarkContextMenu> contextMenu = + ContextMenuFromNode(node_id, embedder, source); + if (contextMenu) { + contextMenu->ExecuteCommand(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO, 0); + } +} + +void BookmarksPageHandler::ExecuteDeleteCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) { + auto embedder = + bookmarks_ui_ ? bookmarks_ui_->embedder() : reading_list_ui_->embedder(); + std::unique_ptr<BookmarkContextMenu> contextMenu = + ContextMenuFromNode(node_id, embedder, source); + if (contextMenu) { + contextMenu->ExecuteCommand(IDC_BOOKMARK_BAR_REMOVE, 0); + } +} + void BookmarksPageHandler::OpenBookmark( int64_t node_id, int32_t parent_folder_depth, @@ -195,22 +262,16 @@ if (!base::StringToInt64(id_string, &id)) return; - Browser* browser = chrome::FindLastActive(); - if (!browser) - return; - - bookmarks::BookmarkModel* bookmark_model = - BookmarkModelFactory::GetForBrowserContext(browser->profile()); - const bookmarks::BookmarkNode* bookmark = - bookmarks::GetBookmarkNodeByID(bookmark_model, id); - if (!bookmark) - return; - auto embedder = bookmarks_ui_ ? bookmarks_ui_->embedder() : reading_list_ui_->embedder(); + if (embedder) { - embedder->ShowContextMenu(point, std::make_unique<BookmarkContextMenu>( - browser, embedder, bookmark, source)); + std::unique_ptr<BookmarkContextMenu> contextMenu = + ContextMenuFromNode(id, embedder, source); + if (contextMenu) { + embedder->ShowContextMenu(point, + ContextMenuFromNode(id, embedder, source)); + } } }
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.h b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.h index 6779e16a..c635740 100644 --- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.h +++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_page_handler.h
@@ -27,6 +27,17 @@ // side_panel::mojom::BookmarksPageHandler: void BookmarkCurrentTabInFolder(int64_t folder_id) override; + void ExecuteOpenInNewTabCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) override; + void ExecuteOpenInNewWindowCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) override; + void ExecuteOpenInIncognitoWindowCommand( + int64_t node_id, + side_panel::mojom::ActionSource source) override; + void ExecuteDeleteCommand(int64_t node_id, + side_panel::mojom::ActionSource source) override; void OpenBookmark(int64_t node_id, int32_t parent_folder_depth, ui::mojom::ClickModifiersPtr click_modifiers,
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc index 352804ad..d2b1fef1 100644 --- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc +++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc
@@ -81,6 +81,8 @@ {"clearSearch", IDS_BOOKMARK_MANAGER_CLEAR_SEARCH}, {"selectedBookmarkCount", IDS_BOOKMARK_MANAGER_ITEMS_SELECTED}, {"menuOpenNewTab", IDS_BOOKMARK_MANAGER_MENU_OPEN_IN_NEW_TAB}, + {"menuOpenNewWindow", IDS_BOOKMARK_MANAGER_MENU_OPEN_IN_NEW_WINDOW}, + {"menuOpenIncognito", IDS_BOOKMARK_MANAGER_MENU_OPEN_INCOGNITO}, {"newFolderTitle", IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME}, }; for (const auto& str : kLocalizedStrings) @@ -97,6 +99,7 @@ base::FeatureList::IsEnabled(features::kUnifiedSidePanel)); source->AddBoolean("guestMode", profile->IsGuestSession()); + source->AddBoolean("incognitoMode", profile->IsIncognitoProfile()); bookmarks::BookmarkModel* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile);
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc index fe11933..c94e7d01 100644 --- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc +++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
@@ -99,6 +99,8 @@ {"clearSearch", IDS_BOOKMARK_MANAGER_CLEAR_SEARCH}, {"selectedBookmarkCount", IDS_BOOKMARK_MANAGER_ITEMS_SELECTED}, {"menuOpenNewTab", IDS_BOOKMARK_MANAGER_MENU_OPEN_IN_NEW_TAB}, + {"menuOpenNewWindow", IDS_BOOKMARK_MANAGER_MENU_OPEN_IN_NEW_WINDOW}, + {"menuOpenIncognito", IDS_BOOKMARK_MANAGER_MENU_OPEN_INCOGNITO}, {"newFolderTitle", IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME}, }; for (const auto& str : kLocalizedStrings) @@ -129,6 +131,7 @@ base::FeatureList::IsEnabled(features::kUnifiedSidePanel)); source->AddBoolean("guestMode", profile->IsGuestSession()); + source->AddBoolean("incognitoMode", profile->IsIncognitoProfile()); source->AddBoolean( "showPowerBookmarks",
diff --git a/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java b/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java index b403cf1..a943886f1 100644 --- a/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java +++ b/chrome/browser/webauthn/android/java/src/org/chromium/chrome/browser/webauthn/CableAuthenticatorModuleProvider.java
@@ -12,7 +12,6 @@ import android.content.Intent; import android.content.res.Resources; import android.graphics.drawable.Drawable; -import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -90,17 +89,6 @@ .setText(getResources().getString( R.string.cablev2_error_code, INSTALL_FAILURE_ERROR_CODE)); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - // While the device will not be advertised in Sync if the Android - // version is too old, this case can occur in the QR flow because - // there's no version restriction on Play Services forwarding the - // `Intent`. - ((TextView) mErrorView.findViewById(R.id.error_description)) - .setText(getResources().getString( - R.string.menu_update_unsupported_summary_default)); - return mErrorView; - } - ((TextView) mErrorView.findViewById(R.id.error_description)) .setText(getResources().getString(R.string.cablev2_error_generic)); @@ -242,8 +230,7 @@ public static boolean canDeviceSupportCable() { // This function will be run on a background thread. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N - || BluetoothAdapter.getDefaultAdapter() == null) { + if (BluetoothAdapter.getDefaultAdapter() == null) { return false; }
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index bde5211..4b49f4aa 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1671709962-5529a0e58e5c9b89902222777c2bda5684a66564.profdata +chrome-mac-arm-main-1671731872-db8e3d4f4de670703661e481bb29570c48a76e6d.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 024515f..4652a6b7 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1671731872-e64a2792eafde6af466e698a236a817d2fcb14c8.profdata +chrome-mac-main-1671753564-41b71bec5177319c3359b2eb986023a9c110138e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index d1e38d61..3f55b21 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1671721064-189024d4b81230d96d5ab1605f78c6009bc20cd6.profdata +chrome-win32-main-1671742794-e0b6d08d0f339d051a2ee6141f4d9be7b903a76e.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 106a9d9..05f1f97 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1671709962-86e5c2f479991b3710dd2b796a8a5ecc2dbf3c7c.profdata +chrome-win64-main-1671742794-968e29ba984d53c216ce69c46e2821893685bdb5.profdata
diff --git a/chrome/chrome_cleaner/components/system_restore_point_component.cc b/chrome/chrome_cleaner/components/system_restore_point_component.cc index ec3ee9f..2626a15 100644 --- a/chrome/chrome_cleaner/components/system_restore_point_component.cc +++ b/chrome/chrome_cleaner/components/system_restore_point_component.cc
@@ -10,7 +10,6 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/win/registry.h" -#include "base/win/windows_version.h" namespace { @@ -71,19 +70,16 @@ if (!set_restore_point_info_fn_) return; - // On Windows8, a registry value needs to be created in order for restore - // points to be deterministically created. Attempt to create this value, but - // continue with the restore point anyway even if doing so fails. See - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa378941.aspx for - // more information. - if (base::win::GetVersion() >= base::win::Version::WIN8) { - base::win::RegKey system_restore_key(HKEY_LOCAL_MACHINE, kSystemRestoreKey, - KEY_SET_VALUE | KEY_QUERY_VALUE); - if (system_restore_key.Valid() && - !system_restore_key.HasValue(kSystemRestoreFrequencyWin8)) { - system_restore_key.WriteValue(kSystemRestoreFrequencyWin8, - static_cast<DWORD>(0)); - } + // A registry value needs to be created in order for restore points to be + // deterministically created. Attempt to create this value, but continue with + // the restore point anyway even if doing so fails. For more info, see + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa378941.aspx. + base::win::RegKey system_restore_key(HKEY_LOCAL_MACHINE, kSystemRestoreKey, + KEY_SET_VALUE | KEY_QUERY_VALUE); + if (system_restore_key.Valid() && + !system_restore_key.HasValue(kSystemRestoreFrequencyWin8)) { + system_restore_key.WriteValue(kSystemRestoreFrequencyWin8, + static_cast<DWORD>(0)); } // Take a system restore point before doing anything else.
diff --git a/chrome/chrome_cleaner/os/task_scheduler_unittest.cc b/chrome/chrome_cleaner/os/task_scheduler_unittest.cc index 1fc8445c..fc0b1eb 100644 --- a/chrome/chrome_cleaner/os/task_scheduler_unittest.cc +++ b/chrome/chrome_cleaner/os/task_scheduler_unittest.cc
@@ -27,10 +27,6 @@ #include "chrome/chrome_cleaner/test/test_strings.h" #include "testing/gtest/include/gtest/gtest.h" -#if BUILDFLAG(IS_WIN) -#include "base/win/windows_version.h" -#endif - namespace chrome_cleaner { namespace { @@ -98,13 +94,6 @@ } TEST_F(TaskSchedulerTests, RunAProgramNow) { -#if BUILDFLAG(IS_WIN) - // TODO(crbug.com/1307401): Failing on Windows7. - if (base::win::GetVersion() <= base::win::Version::WIN7) { - return; - } -#endif - base::FilePath executable_path; ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path)); base::CommandLine command_line(
diff --git a/chrome/chrome_cleaner/test/cleaner_test.cc b/chrome/chrome_cleaner/test/cleaner_test.cc index b83122c..a61c626 100644 --- a/chrome/chrome_cleaner/test/cleaner_test.cc +++ b/chrome/chrome_cleaner/test/cleaner_test.cc
@@ -22,7 +22,6 @@ #include "base/task/thread_pool.h" #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" -#include "base/win/windows_version.h" #include "chrome/chrome_cleaner/buildflags.h" #include "chrome/chrome_cleaner/constants/chrome_cleaner_switches.h" #include "chrome/chrome_cleaner/ipc/chrome_prompt_test_util.h" @@ -550,11 +549,6 @@ } TEST_P(CleanerTest, NoUnsanitizedPaths) { - // Fails on Windows7 - if (base::win::GetVersion() <= base::win::Version::WIN7) { - return; - } - CreateRemovableUwS(); base::CommandLine command_line = BuildCommandLine(kCleanerExecutable);
diff --git a/chrome/chrome_cleaner/test/test_util.cc b/chrome/chrome_cleaner/test/test_util.cc index 5b768055..29172797 100644 --- a/chrome/chrome_cleaner/test/test_util.cc +++ b/chrome/chrome_cleaner/test/test_util.cc
@@ -154,11 +154,6 @@ chrome_cleaner::SandboxType::kNonSandboxed); } - // Some tests spawn sandbox targets using job objects. Windows 7 doesn't - // support nested job objects, so don't use them in the test suite. Otherwise - // all sandbox tests will fail as they try to create a second job object. - bool use_job_objects = base::win::GetVersion() >= base::win::Version::WIN8; - // Some tests will fail if two tests try to launch test_process.exe // simultaneously, so run the tests serially. This will still shard them and // distribute the shards to different swarming bots, but tests will run @@ -167,7 +162,7 @@ argc, argv, /*parallel_jobs=*/1U, // Like LaunchUnitTestsSerially /*default_batch_limit=*/10, // Like LaunchUnitTestsSerially - use_job_objects, base::DoNothing(), + /*use_job_objects=*/true, base::DoNothing(), base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); if (!IsSandboxedProcess())
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 2772c35d..026ccb1 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -99,6 +99,7 @@ "$root_gen_dir/chrome/segmentation_internals_resources.pak", "$root_gen_dir/components/autofill/core/browser/autofill_address_rewriter_resources.pak", "$root_gen_dir/components/components_resources.pak", + "$root_gen_dir/content/attribution_internals_resources.pak", "$root_gen_dir/content/content_resources.pak", "$root_gen_dir/content/indexed_db_resources.pak", "$root_gen_dir/content/quota_internals_resources.pak", @@ -121,6 +122,7 @@ "//components/optimization_guide/optimization_guide_internals/resources", "//components/resources", "//content:content_resources", + "//content/browser/resources/attribution_reporting:resources", "//content/browser/resources/indexed_db:resources", "//content/browser/resources/quota:resources", "//mojo/public/js:resources",
diff --git a/chrome/common/pepper_permission_util_unittest.cc b/chrome/common/pepper_permission_util_unittest.cc index 4484faf..3de709d7 100644 --- a/chrome/common/pepper_permission_util_unittest.cc +++ b/chrome/common/pepper_permission_util_unittest.cc
@@ -25,7 +25,7 @@ scoped_refptr<const Extension> CreateExtensionImportingModule( const std::string& import_id, const std::string& id) { - std::unique_ptr<base::DictionaryValue> manifest = + base::Value::Dict manifest = DictionaryBuilder() .Set("name", "Has Dependent Modules") .Set("version", "1.0") @@ -49,12 +49,11 @@ ScopedCurrentChannel current_channel(version_info::Channel::UNKNOWN); ExtensionSet extensions; std::string allowed_id = crx_file::id_util::GenerateId("allowed_extension"); - std::unique_ptr<base::DictionaryValue> manifest = - DictionaryBuilder() - .Set("name", "Allowed Extension") - .Set("version", "1.0") - .Set("manifest_version", 2) - .Build(); + base::Value::Dict manifest = DictionaryBuilder() + .Set("name", "Allowed Extension") + .Set("version", "1.0") + .Set("manifest_version", 2) + .Build(); scoped_refptr<const Extension> ext = ExtensionBuilder() .SetManifest(std::move(manifest)) .SetID(allowed_id) @@ -86,7 +85,7 @@ std::string allowed_id = crx_file::id_util::GenerateId("extension_id"); std::string bad_id = crx_file::id_util::GenerateId("bad_id"); - std::unique_ptr<base::DictionaryValue> shared_module_manifest = + base::Value::Dict shared_module_manifest = DictionaryBuilder() .Set("name", "Allowed Shared Module") .Set("version", "1.0")
diff --git a/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc b/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc index cc320f8d..17d8ba5c 100644 --- a/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc +++ b/chrome/services/sharing/nearby/platform/wifi_lan_medium_unittest.cc
@@ -9,6 +9,7 @@ #include "base/task/thread_pool.h" #include "base/test/task_environment.h" #include "base/threading/thread_restrictions.h" +#include "base/values.h" #include "chrome/services/sharing/nearby/platform/wifi_lan_server_socket.h" #include "chromeos/ash/components/login/login_state/login_state.h" #include "chromeos/ash/components/network/managed_network_configuration_handler.h" @@ -237,8 +238,8 @@ managed_network_config_handler_->SetPolicy( ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), - /*network_configs_onc=*/base::ListValue(), - /*global_network_config=*/base::DictionaryValue()); + /*network_configs_onc=*/base::Value(base::Value::List()), + /*global_network_config=*/base::Value(base::Value::Dict())); base::RunLoop().RunUntilIdle(); } @@ -256,12 +257,12 @@ void AddWifiService(bool add_ip_configs, const net::IPAddress& local_addr) { if (add_ip_configs) { - base::DictionaryValue ipv4; - ipv4.SetKey(shill::kAddressProperty, base::Value(local_addr.ToString())); - ipv4.SetKey(shill::kMethodProperty, base::Value(shill::kTypeIPv4)); + base::Value::Dict ipv4; + ipv4.Set(shill::kAddressProperty, local_addr.ToString()); + ipv4.Set(shill::kMethodProperty, shill::kTypeIPv4); cros_network_config_helper_->network_state_helper() .ip_config_test() - ->AddIPConfig(kIPv4ConfigPath, ipv4); + ->AddIPConfig(kIPv4ConfigPath, base::Value(std::move(ipv4))); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 496fcc8..51cde89 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3058,6 +3058,8 @@ "../browser/extensions/crx_installer_browsertest.cc", "../browser/extensions/dynamic_origin_browsertest.cc", "../browser/extensions/error_console/error_console_browsertest.cc", + "../browser/extensions/error_console/error_console_test_observer.cc", + "../browser/extensions/error_console/error_console_test_observer.h", "../browser/extensions/events_apitest.cc", "../browser/extensions/extension_action_runner_browsertest.cc", "../browser/extensions/extension_bindings_apitest.cc", @@ -4375,6 +4377,7 @@ "//chromeos/ash/services/auth_factor_config", "//chromeos/ash/services/auth_factor_config", "//chromeos/ash/services/cros_healthd/public/cpp", + "//chromeos/ash/services/device_sync/public/cpp:test_support", "//chromeos/ash/services/multidevice_setup/public/cpp:test_support", "//chromeos/components/onc:test_support", "//chromeos/components/quick_answers/public/cpp:cpp", @@ -7364,6 +7367,7 @@ "../browser/ash/app_list/app_list_test_util.cc", "../browser/ash/app_list/app_list_test_util.h", "../browser/ash/app_list/app_service/app_service_app_model_builder_unittest.cc", + "../browser/ash/app_list/arc/arc_app_sync_metrics_helper_unittest.cc", "../browser/ash/app_list/arc/arc_app_test.cc", "../browser/ash/app_list/arc/arc_app_test.h", "../browser/ash/app_list/arc/arc_app_unittest.cc",
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_observer_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_observer_test.ts index fb3c3b0f..9603dd878 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/ambient_observer_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_observer_test.ts
@@ -6,7 +6,7 @@ import 'chrome://webui-test/mojo_webui_test_support.js'; import {AmbientActionName, AmbientModeAlbum, AmbientObserver, emptyState, SetAlbumsAction, TopicSource} from 'chrome://personalization/js/personalization_app.js'; -import {assertDeepEquals, assertEquals} from 'chrome://webui-test/chai_assert.js'; +import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {baseSetup} from './personalization_app_test_utils.js'; import {TestAmbientProvider} from './test_ambient_interface_provider.js'; @@ -98,3 +98,75 @@ 'used updated regular album url'); }); }); + +suite('GooglePhotosPreviewLoadPerformance', () => { + let ambientProvider: TestAmbientProvider; + let personalizationStore: TestPersonalizationStore; + + setup(() => { + const mocks = baseSetup(); + ambientProvider = mocks.ambientProvider; + personalizationStore = mocks.personalizationStore; + // Reset the value to always start true in test. + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance = true; + AmbientObserver.initAmbientObserverIfNeeded(); + }); + + teardown(() => { + AmbientObserver.shutdown(); + }); + + test('sets to false if ambient mode disabled', async () => { + ambientProvider.ambientObserverRemote!.onAmbientModeEnabledChanged(false); + personalizationStore.expectAction( + AmbientActionName.SET_AMBIENT_MODE_ENABLED); + await personalizationStore.waitForAction( + AmbientActionName.SET_AMBIENT_MODE_ENABLED); + assertFalse(AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance); + }); + + test('sets to false if topic source is not kGooglePhotos', async () => { + ambientProvider.ambientObserverRemote!.onTopicSourceChanged( + TopicSource.kArtGallery); + personalizationStore.expectAction(AmbientActionName.SET_TOPIC_SOURCE); + await personalizationStore.waitForAction( + AmbientActionName.SET_TOPIC_SOURCE); + assertFalse(AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance); + }); + + test('sets to false if already received preview images', async () => { + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = []; + ambientProvider.ambientObserverRemote!.onGooglePhotosAlbumsPreviewsFetched( + []); + personalizationStore.expectAction( + AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS); + await personalizationStore.waitForAction( + AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS); + assertTrue( + AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance, + 'still true because no previews stored yet'); + + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = [ + {url: 'asdf'}, + ]; + ambientProvider.ambientObserverRemote!.onGooglePhotosAlbumsPreviewsFetched( + []); + personalizationStore.expectAction( + AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS); + await personalizationStore.waitForAction( + AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS); + assertFalse(AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance); + }); + + test('sets to false after receiving preview images', async () => { + personalizationStore.data.ambient.googlePhotosAlbumsPreviews = []; + ambientProvider.ambientObserverRemote!.onGooglePhotosAlbumsPreviewsFetched([ + {url: 'asdf'}, + ]); + personalizationStore.expectAction( + AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS); + await personalizationStore.waitForAction( + AmbientActionName.SET_GOOGLE_PHOTOS_ALBUMS_PREVIEWS); + assertFalse(AmbientObserver.shouldLogGooglePhotosPreviewsLoadPerformance); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/device_page_tests.js b/chrome/test/data/webui/settings/chromeos/device_page_tests.js index b4066b39..7ca86db 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/device_page_tests.js
@@ -721,6 +721,9 @@ fakeCrosAudioConfig.defaultFakeSpeaker, fakeCrosAudioConfig.defaultFakeMicJack, ], + + /** @type {!Array<!AudioDevice>} */ + inputDevices: [], }; /** @type {!AudioSystemProperties} */ @@ -735,6 +738,9 @@ fakeCrosAudioConfig.defaultFakeSpeaker, fakeCrosAudioConfig.defaultFakeMicJack, ], + + /** @type {!Array<!AudioDevice>} */ + inputDevices: [], }; /** @type {!AudioSystemProperties} */ @@ -749,6 +755,9 @@ fakeCrosAudioConfig.defaultFakeSpeaker, fakeCrosAudioConfig.defaultFakeMicJack, ], + + /** @type {!Array<!AudioDevice>} */ + inputDevices: [], }; /** @type {!AudioSystemProperties} */ @@ -763,6 +772,9 @@ fakeCrosAudioConfig.defaultFakeSpeaker, fakeCrosAudioConfig.defaultFakeMicJack, ], + + /** @type {!Array<!AudioDevice>} */ + inputDevices: [], }; /** @type {!AudioSystemProperties} */ @@ -774,6 +786,9 @@ /** @type {!Array<!AudioDevice>} */ outputDevices: [], + + /** @type {!Array<!AudioDevice>} */ + inputDevices: [], }; /** @type {!AudioSystemProperties} */ @@ -788,6 +803,9 @@ fakeCrosAudioConfig.fakeSpeakerActive, fakeCrosAudioConfig.fakeMicJackInactive, ], + + /** @type {!Array<!AudioDevice>} */ + inputDevices: [], }; /** @@ -819,6 +837,9 @@ // FakeAudioConfig must be set before audio subpage is loaded. crosAudioConfig = new fakeCrosAudioConfig.FakeCrosAudioConfig(); setCrosAudioConfigForTesting(crosAudioConfig); + // Ensure data reset to fresh state. + crosAudioConfig.setAudioSystemProperties( + {...fakeCrosAudioConfig.defaultFakeAudioSystemProperties}); return showAndGetDeviceSubpage('audio', routes.AUDIO) .then(function(page) { audioPage = page; @@ -887,9 +908,8 @@ await flushTasks(); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .outputVolumePercent, - minOutputVolumePercent); + minOutputVolumePercent, + audioPage.audioSystemProperties_.outputVolumePercent); // Ensure value clamps to min. outputSlider.value = 101; @@ -897,9 +917,8 @@ await flushTasks(); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .outputVolumePercent, - maxOutputVolumePercent); + maxOutputVolumePercent, + audioPage.audioSystemProperties_.outputVolumePercent); }); test('output mute state changes slider disabled state', async function() { @@ -1073,8 +1092,7 @@ const inputSlider = audioPage.shadowRoot.querySelector(sliderSelector); assertTrue(isVisible(inputSlider)); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .inputVolumePercent, + audioPage.audioSystemProperties_.inputVolumePercent, inputSlider.value); const minimumValue = 0; @@ -1082,24 +1100,21 @@ assertEquals(minimumValue, inputSlider.value); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .inputVolumePercent, + audioPage.audioSystemProperties_.inputVolumePercent, inputSlider.value); const maximumValue = 100; await simulateSliderClicked(sliderSelector, maximumValue); assertEquals(maximumValue, inputSlider.value); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .inputVolumePercent, + audioPage.audioSystemProperties_.inputVolumePercent, inputSlider.value); const middleValue = 50; await simulateSliderClicked(sliderSelector, middleValue); assertEquals(middleValue, inputSlider.value); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .inputVolumePercent, + audioPage.audioSystemProperties_.inputVolumePercent, inputSlider.value); // Ensure value clamps to min. @@ -1108,9 +1123,7 @@ await flushTasks(); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .inputVolumePercent, - minimumValue); + audioPage.audioSystemProperties_.inputVolumePercent, minimumValue); // Ensure value clamps to min. inputSlider.value = 101; @@ -1118,9 +1131,7 @@ await flushTasks(); assertEquals( - fakeCrosAudioConfig.defaultFakeAudioSystemProperties - .inputVolumePercent, - maximumValue); + audioPage.audioSystemProperties_.inputVolumePercent, maximumValue); }); });
diff --git a/chrome/test/data/webui/side_panel/bookmarks/test_bookmarks_api_proxy.ts b/chrome/test/data/webui/side_panel/bookmarks/test_bookmarks_api_proxy.ts index 1269de4..47adfa87 100644 --- a/chrome/test/data/webui/side_panel/bookmarks/test_bookmarks_api_proxy.ts +++ b/chrome/test/data/webui/side_panel/bookmarks/test_bookmarks_api_proxy.ts
@@ -28,6 +28,10 @@ 'bookmarkCurrentTabInFolder', 'openBookmark', 'cutBookmark', + 'contextMenuOpenBookmarkInNewTab', + 'contextMenuOpenBookmarkInNewWindow', + 'contextMenuOpenBookmarkInIncognitoWindow', + 'contextMenuDelete', 'copyBookmark', 'createFolder', 'deleteBookmarks', @@ -72,6 +76,22 @@ this.folders_ = folders; } + contextMenuOpenBookmarkInNewTab(id: string, source: ActionSource) { + this.methodCalled('contextMenuOpenBookmarkInNewTab', id, source); + } + + contextMenuOpenBookmarkInNewWindow(id: string, source: ActionSource) { + this.methodCalled('contextMenuOpenBookmarkInNewWindow', id, source); + } + + contextMenuOpenBookmarkInIncognitoWindow(id: string, source: ActionSource) { + this.methodCalled('contextMenuOpenBookmarkInIncognitoWindow', id, source); + } + + contextMenuDelete(id: string, source: ActionSource) { + this.methodCalled('contextMenuDelete', id, source); + } + copyBookmark(id: string): Promise<void> { this.methodCalled('copyBookmark', id); return Promise.resolve();
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_service_impl.cc b/chromecast/cast_core/runtime/browser/runtime_application_service_impl.cc index 1687dad..e21ed22 100644 --- a/chromecast/cast_core/runtime/browser/runtime_application_service_impl.cc +++ b/chromecast/cast_core/runtime/browser/runtime_application_service_impl.cc
@@ -238,7 +238,7 @@ runtime_application_->Launch(std::move(callback)); } -void RuntimeApplicationServiceImpl::LoadPage(const GURL& url) { +void RuntimeApplicationServiceImpl::NavigateToPage(const GURL& url) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto* cast_web_contents = cast_web_view_->cast_web_contents();
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h b/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h index d56217c..0441a83 100644 --- a/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h +++ b/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h
@@ -75,7 +75,7 @@ #if !BUILDFLAG(IS_CAST_DESKTOP_BUILD) cast_receiver::StreamingConfigManager* GetStreamingConfigManager() override; #endif - void LoadPage(const GURL& url) override; + void NavigateToPage(const GURL& url) override; private: // Gets the current |message_port_service_|, attempting to create it if it
diff --git a/chromeos/ash/components/network/cellular_connection_handler.cc b/chromeos/ash/components/network/cellular_connection_handler.cc index 12aa36f..586f5b1 100644 --- a/chromeos/ash/components/network/cellular_connection_handler.cc +++ b/chromeos/ash/components/network/cellular_connection_handler.cc
@@ -75,6 +75,9 @@ } // namespace // static +const base::TimeDelta CellularConnectionHandler::kWaitingForAutoConnectTimeout = + base::Minutes(2); + absl::optional<std::string> CellularConnectionHandler::ResultToErrorString( PrepareCellularConnectionResult result) { switch (result) { @@ -216,7 +219,8 @@ } void CellularConnectionHandler::CompleteConnectionAttempt( - PrepareCellularConnectionResult result) { + PrepareCellularConnectionResult result, + bool auto_connected) { DCHECK(state_ != ConnectionState::kIdle); DCHECK(!request_queue_.empty()); @@ -244,7 +248,7 @@ std::move(metadata->error_callback) .Run(service_path, NetworkConnectionHandler::kErrorNotFound); } else { - std::move(metadata->success_callback).Run(service_path); + std::move(metadata->success_callback).Run(service_path, auto_connected); } ProcessRequestQueue(); @@ -322,14 +326,16 @@ NET_LOG(ERROR) << "Could not find network for ICCID " << *request_queue_.front()->iccid; CompleteConnectionAttempt( - PrepareCellularConnectionResult::kCouldNotFindNetworkWithIccid); + PrepareCellularConnectionResult::kCouldNotFindNetworkWithIccid, + /*auto_connected=*/false); return; } if (CanInitiateShillConnection(network_state)) { NET_LOG(USER) << "Cellular service with ICCID " << iccid << " is connectable"; - CompleteConnectionAttempt(PrepareCellularConnectionResult::kSuccess); + CompleteConnectionAttempt(PrepareCellularConnectionResult::kSuccess, + /*auto_connected=*/false); return; } @@ -362,7 +368,8 @@ if (!inhibit_lock) { NET_LOG(ERROR) << "eSIM connection flow failed to inhibit scan"; - CompleteConnectionAttempt(PrepareCellularConnectionResult::kInhibitFailed); + CompleteConnectionAttempt(PrepareCellularConnectionResult::kInhibitFailed, + /*auto_connected=*/false); return; } @@ -378,7 +385,8 @@ if (!euicc_path) { NET_LOG(ERROR) << "eSIM connection flow could not find relevant EUICC"; CompleteConnectionAttempt( - PrepareCellularConnectionResult::kCouldNotFindRelevantEuicc); + PrepareCellularConnectionResult::kCouldNotFindRelevantEuicc, + /*auto_connected=*/false); return; } @@ -396,7 +404,8 @@ if (!inhibit_lock) { NET_LOG(ERROR) << "eSIM connection flow failed to request profiles"; CompleteConnectionAttempt( - PrepareCellularConnectionResult::kRefreshProfilesFailed); + PrepareCellularConnectionResult::kRefreshProfilesFailed, + /*auto_connected=*/false); return; } @@ -412,7 +421,8 @@ if (!profile_path) { NET_LOG(ERROR) << "eSIM connection flow could not find profile"; CompleteConnectionAttempt( - PrepareCellularConnectionResult::kCouldNotFindRelevantESimProfile); + PrepareCellularConnectionResult::kCouldNotFindRelevantESimProfile, + /*auto_connected=*/false); return; } @@ -436,10 +446,15 @@ if (!success) { NET_LOG(ERROR) << "eSIM connection flow failed to enable profile"; CompleteConnectionAttempt( - PrepareCellularConnectionResult::kEnableProfileFailed); + PrepareCellularConnectionResult::kEnableProfileFailed, + /*auto_connected=*/false); return; } + // kErrorAlreadyEnabled implies that the SIM profile was already enabled. + request_queue_.front()->did_connection_require_enabling_profile = + status == HermesResponseStatus::kSuccess; + // Reset the inhibit_lock so that the device will be uninhibited // automatically. request_queue_.front()->inhibit_lock.reset(); @@ -452,12 +467,24 @@ CheckForConnectable(); } +void CellularConnectionHandler::NetworkConnectionStateChanged( + const NetworkState* network) { + if (state_ == ConnectionState::kWaitingForShillAutoConnect) { + CheckForAutoConnected(); + } +} + void CellularConnectionHandler::CheckForConnectable() { DCHECK_EQ(state_, ConnectionState::kWaitingForConnectable); const NetworkState* network_state = GetNetworkStateForCurrentOperation(); if (network_state && CanInitiateShillConnection(network_state)) { - CompleteConnectionAttempt(PrepareCellularConnectionResult::kSuccess); + if (!request_queue_.front()->did_connection_require_enabling_profile) { + CompleteConnectionAttempt(PrepareCellularConnectionResult::kSuccess, + /*auto_connected=*/false); + } else { + StartWaitingForShillAutoConnect(); + } return; } @@ -477,7 +504,46 @@ NET_LOG(ERROR) << "Cellular connection timed out waiting for network to " "become connectable"; CompleteConnectionAttempt( - PrepareCellularConnectionResult::kTimeoutWaitingForConnectable); + PrepareCellularConnectionResult::kTimeoutWaitingForConnectable, + /*auto_connected=*/false); +} + +void CellularConnectionHandler::StartWaitingForShillAutoConnect() { + // Stop the timer that wait for the network to become connectable. + if (timer_.IsRunning()) { + timer_.Stop(); + } + + TransitionToConnectionState(ConnectionState::kWaitingForShillAutoConnect); + CheckForAutoConnected(); +} + +void CellularConnectionHandler::CheckForAutoConnected() { + CHECK_EQ(state_, ConnectionState::kWaitingForShillAutoConnect); + + const NetworkState* network_state = GetNetworkStateForCurrentOperation(); + if (network_state && network_state->IsConnectedState()) { + CompleteConnectionAttempt(PrepareCellularConnectionResult::kSuccess, + /*auto_connected=*/true); + return; + } + + // If network hasn't autoconnected by Shill yet, start a timer and wait for + // the network to become connected. + if (!timer_.IsRunning()) { + timer_.Start( + FROM_HERE, kWaitingForAutoConnectTimeout, + base::BindOnce(&CellularConnectionHandler::OnWaitForAutoConnectTimeout, + weak_ptr_factory_.GetWeakPtr())); + } +} + +void CellularConnectionHandler::OnWaitForAutoConnectTimeout() { + DCHECK_EQ(state_, ConnectionState::kWaitingForShillAutoConnect); + NET_LOG(ERROR) << "Cellular connection timed out waiting for network to " + "become auto connected"; + CompleteConnectionAttempt(PrepareCellularConnectionResult::kSuccess, + /*auto_connected=*/false); } std::ostream& operator<<( @@ -503,6 +569,10 @@ case CellularConnectionHandler::ConnectionState::kWaitingForConnectable: stream << "[Waiting for network to become connectable]"; break; + case CellularConnectionHandler::ConnectionState:: + kWaitingForShillAutoConnect: + stream << "[Waiting for network to become auto-connected]"; + break; } return stream; }
diff --git a/chromeos/ash/components/network/cellular_connection_handler.h b/chromeos/ash/components/network/cellular_connection_handler.h index f05d9dfa..733afb1 100644 --- a/chromeos/ash/components/network/cellular_connection_handler.h +++ b/chromeos/ash/components/network/cellular_connection_handler.h
@@ -21,6 +21,10 @@ namespace ash { +namespace cellular_setup { +class ESimTestBase; +} + class CellularESimProfileHandler; class CellularInhibitor; class NetworkState; @@ -46,6 +50,7 @@ // (4) Enable the relevant profile. // (5) Uninhibit cellular scans. // (6) Wait until the associated NetworkState becomes connectable. +// (7) Wait until Shill auto connected if the sim slot is switched. // // Note that if this class receives multiple connection requests, it processes // them in FIFO order. @@ -62,8 +67,10 @@ CellularInhibitor* cellular_inhibitor, CellularESimProfileHandler* cellular_esim_profile_handler); - // Success callback which receives the network's service path as a parameter. - typedef base::OnceCallback<void(const std::string&)> SuccessCallback; + // Success callback which receives the network's service path as the first + // parameter and a boolean indicates whether the network is autoconnected + // as the second parameter. + typedef base::OnceCallback<void(const std::string&, bool)> SuccessCallback; // Error callback which receives the network's service path as the first // parameter and an error name as the second parameter. If no service path is @@ -93,6 +100,11 @@ private: friend class CellularConnectionHandlerTest; + friend class CellularESimInstallerTest; + friend class CellularPolicyHandlerTest; + friend class ManagedNetworkConfigurationHandlerTest; + friend class cellular_setup::ESimTestBase; + FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, NoService); FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, ServiceAlreadyConnectable); @@ -104,7 +116,10 @@ TimeoutWaitingForConnectable_ESim); FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, TimeoutWaitingForConnectable_PSim); - FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, Success); + FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, + Success_AutoConnected); + FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, + Success_TimeoutAutoConnected); FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, Success_AlreadyEnabled); FRIEND_TEST_ALL_PREFIXES(CellularConnectionHandlerTest, ConnectToStub); @@ -127,6 +142,9 @@ absl::optional<dbus::ObjectPath> euicc_path; absl::optional<dbus::ObjectPath> profile_path; std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock; + // A boolean indicating that if the connection switches the SIM profile and + // requires enabling the profile first. + bool did_connection_require_enabling_profile = false; SuccessCallback success_callback; ErrorCallback error_callback; }; @@ -137,7 +155,8 @@ kInhibitingScans, kRequestingProfilesBeforeEnabling, kEnablingProfile, - kWaitingForConnectable + kWaitingForConnectable, + kWaitingForShillAutoConnect, }; friend std::ostream& operator<<(std::ostream& stream, const ConnectionState& step); @@ -155,6 +174,10 @@ kTimeoutWaitingForConnectable = 7, kMaxValue = kTimeoutWaitingForConnectable }; + + // Timeout waiting for a cellular network to auto connect after switch + // profile. + static const base::TimeDelta kWaitingForAutoConnectTimeout; static absl::optional<std::string> ResultToErrorString( PrepareCellularConnectionResult result); @@ -165,12 +188,15 @@ const std::string& new_service_path, const std::string& old_guid, const std::string& new_guid) override; + void NetworkConnectionStateChanged(const NetworkState* network) override; void ProcessRequestQueue(); void TransitionToConnectionState(ConnectionState state); - // Invokes the success or error callback, depending on |result|. - void CompleteConnectionAttempt(PrepareCellularConnectionResult result); + // Invokes the success or error callback, depending on |result| and + // |auto_connected|. + void CompleteConnectionAttempt(PrepareCellularConnectionResult result, + bool auto_connected); const NetworkState* GetNetworkStateForCurrentOperation() const; absl::optional<dbus::ObjectPath> GetEuiccPathForCurrentOperation() const; @@ -193,6 +219,9 @@ void HandleNetworkPropertiesUpdate(); void CheckForConnectable(); void OnWaitForConnectableTimeout(); + void StartWaitingForShillAutoConnect(); + void CheckForAutoConnected(); + void OnWaitForAutoConnectTimeout(); base::OneShotTimer timer_;
diff --git a/chromeos/ash/components/network/cellular_connection_handler_unittest.cc b/chromeos/ash/components/network/cellular_connection_handler_unittest.cc index 49bd5a60..e97ec23a 100644 --- a/chromeos/ash/components/network/cellular_connection_handler_unittest.cc +++ b/chromeos/ash/components/network/cellular_connection_handler_unittest.cc
@@ -114,6 +114,13 @@ base::RunLoop().RunUntilIdle(); } + void SetCellularServiceConnected(int profile_num) { + helper_.service_test()->SetServiceProperty( + CreateTestServicePath(profile_num), shill::kStateProperty, + base::Value(shill::kStateOnline)); + base::RunLoop().RunUntilIdle(); + } + void ExpectServiceConnectable(int profile_num) { const NetworkState* network_state = helper_.network_state_handler()->GetNetworkState( @@ -194,8 +201,10 @@ } void ExpectSuccess(const std::string& expected_service_path, - base::RunLoop* run_loop) { + base::RunLoop* run_loop, + bool auto_connected) { expected_service_path_ = expected_service_path; + expected_auto_connected_ = auto_connected; on_success_callback_ = run_loop->QuitClosure(); } @@ -236,8 +245,9 @@ } private: - void OnSuccess(const std::string& service_path) { + void OnSuccess(const std::string& service_path, bool auto_connected) { EXPECT_EQ(expected_service_path_, service_path); + EXPECT_EQ(expected_auto_connected_, auto_connected); std::move(on_success_callback_).Run(); } @@ -260,6 +270,7 @@ base::OnceClosure on_success_callback_; base::OnceClosure on_failure_callback_; std::string expected_service_path_; + bool expected_auto_connected_; std::string expected_error_name_; }; @@ -283,7 +294,8 @@ SetServiceConnectable(/*profile_num=*/1); base::RunLoop run_loop; - ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop, + /*auto_connected=*/false); CallPrepareExistingCellularNetworkForConnection(/*profile_num=*/1); run_loop.Run(); @@ -397,7 +409,7 @@ kTimeoutWaitingForConnectable); } -TEST_F(CellularConnectionHandlerTest, Success) { +TEST_F(CellularConnectionHandlerTest, Success_AutoConnected) { AddCellularDevice(); AddEuicc(/*euicc_num=*/1); AddProfile(/*profile_num=*/1, /*euicc_num=*/1); @@ -405,7 +417,29 @@ SetServiceIccid(/*profile_num=*/1); base::RunLoop run_loop; - ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop, + /*auto_connected=*/true); + CallPrepareExistingCellularNetworkForConnection(/*profile_num=*/1); + // Simulate the cellular network get connected after 10 seconds. + AdvanceClock(base::Seconds(10)); + SetCellularServiceConnected(/*profile_num=*/1); + run_loop.Run(); + + ExpectServiceConnectable(/*profile_num=*/1); + ExpectResult( + CellularConnectionHandler::PrepareCellularConnectionResult::kSuccess); +} + +TEST_F(CellularConnectionHandlerTest, Success_TimeoutAutoConnected) { + AddCellularDevice(); + AddEuicc(/*euicc_num=*/1); + AddProfile(/*profile_num=*/1, /*euicc_num=*/1); + SetServiceEid(/*profile_num=*/1, /*euicc_num=*/1); + SetServiceIccid(/*profile_num=*/1); + + base::RunLoop run_loop; + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop, + /*auto_connected=*/false); CallPrepareExistingCellularNetworkForConnection(/*profile_num=*/1); run_loop.Run(); @@ -425,7 +459,8 @@ SetServiceIccid(/*profile_num=*/1); base::RunLoop run_loop; - ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop, + /*auto_connected=*/false); CallPrepareExistingCellularNetworkForConnection(/*profile_num=*/1); SetServiceConnectable(/*profile_num=*/1); run_loop.Run(); @@ -445,7 +480,8 @@ base::RunLoop run_loop; // Expect that by the end, we will connect to a "real" (i.e., non-stub) // service path. - ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop, + /*auto_connected=*/false); CallPrepareExistingCellularNetworkForConnection(/*profile_num=*/1); base::RunLoop().RunUntilIdle(); @@ -473,7 +509,8 @@ SetServiceIccid(/*profile_num=*/2); base::RunLoop run_loop1; - ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop1); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop1, + /*auto_connected=*/false); // Start both operations. CallPrepareExistingCellularNetworkForConnection(/*profile_num=*/1); @@ -484,7 +521,8 @@ ExpectServiceConnectable(/*profile_num=*/1); base::RunLoop run_loop2; - ExpectSuccess(CreateTestServicePath(/*profile_num=*/2), &run_loop2); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/2), &run_loop2, + /*auto_connected=*/false); // Verify that the second service becomes connectable. run_loop2.Run(); @@ -501,9 +539,10 @@ AddProfile(/*profile_num=*/1, /*euicc_num=*/1); base::RunLoop run_loop; - ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop); - CallPrepareNewlyInstalledCellularNetworkForConnection(/*euicc_num=*/1, - /*profile_num=*/1); + ExpectSuccess(CreateTestServicePath(/*profile_num=*/1), &run_loop, + /*auto_connected=*/false); + CallPrepareNewlyInstalledCellularNetworkForConnection(/*profile_num=*/1, + /*euicc_num=*/1); // Verify that service corresponding to new profile becomes // connectable.
diff --git a/chromeos/ash/components/network/cellular_esim_installer.cc b/chromeos/ash/components/network/cellular_esim_installer.cc index 0a87fed..7b027c0 100644 --- a/chromeos/ash/components/network/cellular_esim_installer.cc +++ b/chromeos/ash/components/network/cellular_esim_installer.cc
@@ -298,7 +298,8 @@ void CellularESimInstaller::OnPrepareCellularNetworkForConnectionSuccess( const dbus::ObjectPath& profile_path, InstallProfileFromActivationCodeCallback callback, - const std::string& service_path) { + const std::string& service_path, + bool auto_connected) { NET_LOG(EVENT) << "Successfully enabled installed profile on service path: " << service_path; const NetworkState* network_state =
diff --git a/chromeos/ash/components/network/cellular_esim_installer.h b/chromeos/ash/components/network/cellular_esim_installer.h index 68ff439..e60c328 100644 --- a/chromeos/ash/components/network/cellular_esim_installer.h +++ b/chromeos/ash/components/network/cellular_esim_installer.h
@@ -96,6 +96,8 @@ InstallProfileConnectFailure); FRIEND_TEST_ALL_PREFIXES(CellularESimInstallerTest, InstallProfileSuccess); FRIEND_TEST_ALL_PREFIXES(CellularESimInstallerTest, + InstallProfileAutoConnect); + FRIEND_TEST_ALL_PREFIXES(CellularESimInstallerTest, InstallProfileViaQrCodeSuccess); FRIEND_TEST_ALL_PREFIXES(CellularESimInstallerTest, InstallProfileAlreadyConnected); @@ -153,7 +155,8 @@ void OnPrepareCellularNetworkForConnectionSuccess( const dbus::ObjectPath& profile_path, InstallProfileFromActivationCodeCallback callback, - const std::string& service_path); + const std::string& service_path, + bool auto_connected); void OnPrepareCellularNetworkForConnectionFailure( const dbus::ObjectPath& profile_path, InstallProfileFromActivationCodeCallback callback,
diff --git a/chromeos/ash/components/network/cellular_esim_installer_unittest.cc b/chromeos/ash/components/network/cellular_esim_installer_unittest.cc index 7960cee..752d9258 100644 --- a/chromeos/ash/components/network/cellular_esim_installer_unittest.cc +++ b/chromeos/ash/components/network/cellular_esim_installer_unittest.cc
@@ -44,6 +44,7 @@ const char kTestEuiccPath[] = "/org/chromium/Hermes/Euicc/0"; const char kTestEid[] = "12345678901234567890123456789012"; +const char kTestCellularServicePath[] = "/service/cellular101"; const char kInstallViaQrCodeHistogram[] = "Network.Cellular.ESim.InstallViaQrCode.Result"; const char kESimInstallNonUserErrorSuccessRate[] = @@ -151,7 +152,8 @@ bool wait_for_connect, bool fail_connect, bool is_initial_install = true, - bool is_install_via_qr_code = false) { + bool is_install_via_qr_code = false, + bool auto_connected = false) { HermesResponseStatus out_install_result; absl::optional<dbus::ObjectPath> out_esim_profile_path; absl::optional<std::string> out_service_path; @@ -174,15 +176,23 @@ FastForwardProfileRefreshDelay(); if (wait_for_connect) { - base::RunLoop().RunUntilIdle(); - EXPECT_LE(1u, network_connection_handler_->connect_calls().size()); - if (fail_connect) { - network_connection_handler_->connect_calls().back().InvokeErrorCallback( - "fake_error_name"); + if (auto_connected) { + ShillServiceClient::Get()->GetTestInterface()->SetServiceProperty( + kTestCellularServicePath, shill::kStateProperty, + base::Value(shill::kStateOnline)); } else { - network_connection_handler_->connect_calls() - .back() - .InvokeSuccessCallback(); + FastForwardAutoConnectWaiting(); + base::RunLoop().RunUntilIdle(); + EXPECT_LE(1u, network_connection_handler_->connect_calls().size()); + if (fail_connect) { + network_connection_handler_->connect_calls() + .back() + .InvokeErrorCallback("fake_error_name"); + } else { + network_connection_handler_->connect_calls() + .back() + .InvokeSuccessCallback(); + } } } @@ -284,6 +294,11 @@ task_environment_.FastForwardBy(2 * kProfileRefreshCallbackDelay); } + void FastForwardAutoConnectWaiting() { + task_environment_.FastForwardBy( + CellularConnectionHandler::kWaitingForAutoConnectTimeout); + } + base::HistogramTester* HistogramTesterPtr() { return &histogram_tester_; } private: @@ -430,7 +445,32 @@ /*euicc_path=*/dbus::ObjectPath(kTestEuiccPath), /*new_shill_properties=*/base::Value(base::Value::Type::DICTIONARY), /*wait_for_connect=*/true, /*fail_connect=*/false, - /*is_initial_install=*/true, /*install_via_qr_code=*/true); + /*is_initial_install=*/true, /*is_install_via_qr_code=*/true); + CheckInstallSuccess(result_tuple); + + HistogramTesterPtr()->ExpectTotalCount(kESimProfileDownloadLatencyHistogram, + 1); + CheckESimInstallHistograms( + /*expected_count=*/1, HermesResponseStatus::kSuccess, + CellularESimInstaller::InstallESimProfileResult::kSuccess); + CheckDetailedESimInstallHistograms( + CellularESimInstaller::InstallESimProfileResult::kSuccess, + /*is_managed=*/false, /*is_retry=*/false, + /*is_install_via_qr_code=*/true); +} + +TEST_F(CellularESimInstallerTest, InstallProfileAutoConnect) { + // Verify that install succeeds when valid activation code is passed. + InstallResultTuple result_tuple = InstallProfileFromActivationCode( + HermesEuiccClient::Get() + ->GetTestInterface() + ->GenerateFakeActivationCode(), + /*confirmation_code=*/std::string(), + /*euicc_path=*/dbus::ObjectPath(kTestEuiccPath), + /*new_shill_properties=*/base::Value(base::Value::Type::DICTIONARY), + /*wait_for_connect=*/true, /*fail_connect=*/false, + /*is_initial_install=*/true, /*is_install_via_qr_code=*/true, + /*auto_connected=*/true); CheckInstallSuccess(result_tuple); HistogramTesterPtr()->ExpectTotalCount(kESimProfileDownloadLatencyHistogram,
diff --git a/chromeos/ash/components/network/cellular_policy_handler.cc b/chromeos/ash/components/network/cellular_policy_handler.cc index f46a7ce8..aafee1d 100644 --- a/chromeos/ash/components/network/cellular_policy_handler.cc +++ b/chromeos/ash/components/network/cellular_policy_handler.cc
@@ -295,7 +295,8 @@ HermesProfileClient::Properties* profile_properties = HermesProfileClient::Get()->GetProperties(*profile_path); managed_cellular_pref_handler_->AddIccidSmdpPair( - profile_properties->iccid().value(), current_request->smdp_address); + profile_properties->iccid().value(), current_request->smdp_address, + /*sync_stub_networks=*/false); managed_network_configuration_handler_->NotifyPolicyAppliedToNetwork( *service_path);
diff --git a/chromeos/ash/components/network/cellular_policy_handler_unittest.cc b/chromeos/ash/components/network/cellular_policy_handler_unittest.cc index da5b2c7..4d211b2 100644 --- a/chromeos/ash/components/network/cellular_policy_handler_unittest.cc +++ b/chromeos/ash/components/network/cellular_policy_handler_unittest.cc
@@ -42,7 +42,7 @@ const char kTestEuiccPath2[] = "/org/chromium/Hermes/Euicc/1"; const char kTestESimProfilePath[] = "/org/chromium/Hermes/Euicc/1/Profile/1000000000000000002"; -const char kTesServicePath[] = "/service/1"; +const char kTestServicePath[] = "/service/cellular102"; const char kTestEid[] = "12345678901234567890123456789012"; const char kTestEid2[] = "12345678901234567890123456789000"; const char kCellularGuid[] = "cellular_guid"; @@ -177,7 +177,7 @@ dbus::ObjectPath(kTestEuiccPath), kICCID, /*name=*/std::string(), /*nickname=*/std::string(), /*service_provider=*/std::string(), /*activation_code=*/std::string(), - kTesServicePath, hermes::profile::State::kInactive, + kTestServicePath, hermes::profile::State::kInactive, hermes::profile::ProfileClass::kOperational, HermesEuiccClient::TestInterface::AddCarrierProfileBehavior:: kAddProfileWithoutService); @@ -205,19 +205,24 @@ void InstallESimPolicy(const std::string& onc_json, const std::string& activation_code, - bool expect_install_success) { + bool expect_install_success, + bool auto_connect = false) { base::Value policy = chromeos::onc::ReadDictionaryFromJson(onc_json); cellular_policy_handler_->InstallESim(activation_code, policy); FastForwardProfileRefreshDelay(); base::RunLoop().RunUntilIdle(); - if (expect_install_success) { + if (!expect_install_success) { + EXPECT_LE(0u, network_connection_handler_->connect_calls().size()); + return; + } + FastForwardAutoConnectWaiting(auto_connect); + base::RunLoop().RunUntilIdle(); + if (!auto_connect) { EXPECT_LE(1u, network_connection_handler_->connect_calls().size()); network_connection_handler_->connect_calls() .back() .InvokeSuccessCallback(); - } else { - EXPECT_LE(0u, network_connection_handler_->connect_calls().size()); } base::RunLoop().RunUntilIdle(); } @@ -241,6 +246,19 @@ FastForwardBy(2 * kProfileRefreshCallbackDelay); } + void FastForwardAutoConnectWaiting(bool auto_connect) { + if (auto_connect) { + task_environment_.FastForwardBy(base::Seconds(10)); + ShillServiceClient::Get()->GetTestInterface()->SetServiceProperty( + kTestServicePath, shill::kStateProperty, + base::Value(shill::kStateOnline)); + return; + } + + task_environment_.FastForwardBy( + CellularConnectionHandler::kWaitingForAutoConnectTimeout); + } + void FastForwardBy(base::TimeDelta delay) { task_environment_.FastForwardBy(delay); } @@ -279,7 +297,8 @@ HermesEuiccClient::Get() ->GetTestInterface() ->GenerateFakeActivationCode(), - /*expect_install_success=*/true); + /*expect_install_success=*/true, + /*auto_connect=*/true); CheckShillConfiguration(/*is_installed=*/true); CheckIccidSmdpPairInPref(/*is_installed=*/true); @@ -318,6 +337,7 @@ ShillDeviceClient::Get()->GetTestInterface()->AddDevice( "/device/cellular1", shill::kTypeCellular, "TestCellular"); FastForwardProfileRefreshDelay(); + FastForwardAutoConnectWaiting(/*auto_connect=*/false); base::RunLoop().RunUntilIdle(); CheckShillConfiguration(/*is_installed=*/true); } @@ -338,6 +358,7 @@ CheckShillConfiguration(/*is_installed=*/false); SetupEuicc(); FastForwardProfileRefreshDelay(); + FastForwardAutoConnectWaiting(/*auto_connect=*/false); base::RunLoop().RunUntilIdle(); CheckShillConfiguration(/*is_installed=*/true); CheckIccidSmdpPairInPref(/*is_installed=*/true);
diff --git a/chromeos/ash/components/network/managed_cellular_pref_handler.cc b/chromeos/ash/components/network/managed_cellular_pref_handler.cc index da9a0f9..0e186db 100644 --- a/chromeos/ash/components/network/managed_cellular_pref_handler.cc +++ b/chromeos/ash/components/network/managed_cellular_pref_handler.cc
@@ -50,7 +50,8 @@ void ManagedCellularPrefHandler::AddIccidSmdpPair( const std::string& iccid, - const std::string& smdp_address) { + const std::string& smdp_address, + bool sync_stub_networks) { if (!device_prefs_) { NET_LOG(ERROR) << "Device pref not available yet."; return; @@ -64,7 +65,10 @@ ScopedDictPrefUpdate update(device_prefs_, prefs::kManagedCellularIccidSmdpPair); update->SetByDottedPath(iccid, smdp_address); - network_state_handler_->SyncStubCellularNetworks(); + if (sync_stub_networks) { + network_state_handler_->SyncStubCellularNetworks(); + } + NotifyManagedCellularPrefChanged(); }
diff --git a/chromeos/ash/components/network/managed_cellular_pref_handler.h b/chromeos/ash/components/network/managed_cellular_pref_handler.h index 40093037..f5f98f1 100644 --- a/chromeos/ash/components/network/managed_cellular_pref_handler.h +++ b/chromeos/ash/components/network/managed_cellular_pref_handler.h
@@ -41,9 +41,11 @@ void SetDevicePrefs(PrefService* device_prefs); // Add a new ICCID and SMDP+ address pair to device pref for a managed - // cellular network. + // cellular network. If |sync_stub_networks| is set true, + // NetworkStateHandler::SyncStubCellularNetworks() will be called. void AddIccidSmdpPair(const std::string& iccid, - const std::string& smdp_address); + const std::string& smdp_address, + bool sync_stub_networks = true); // Remove the ICCID and SMDP+ address pair from the device pref with given // |iccid|.
diff --git a/chromeos/ash/components/network/managed_network_configuration_handler_unittest.cc b/chromeos/ash/components/network/managed_network_configuration_handler_unittest.cc index f96001c..dff9fdc 100644 --- a/chromeos/ash/components/network/managed_network_configuration_handler_unittest.cc +++ b/chromeos/ash/components/network/managed_network_configuration_handler_unittest.cc
@@ -358,6 +358,11 @@ task_environment_.FastForwardBy(2 * kProfileRefreshCallbackDelay); } + void FastForwardAutoConnectWaiting() { + task_environment_.FastForwardBy( + CellularConnectionHandler::kWaitingForAutoConnectTimeout); + } + ProhibitedTechnologiesHandler* prohibited_technologies_handler() { return prohibited_technologies_handler_.get(); } @@ -614,6 +619,7 @@ SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(), "policy/policy_cellular.onc"); FastForwardProfileRefreshDelay(); + FastForwardAutoConnectWaiting(); base::RunLoop().RunUntilIdle(); std::string service_path = GetShillServiceClient()->FindServiceMatchingGUID(
diff --git a/chromeos/ash/components/network/network_connection_handler_impl.cc b/chromeos/ash/components/network/network_connection_handler_impl.cc index 8956505d..bbf149b 100644 --- a/chromeos/ash/components/network/network_connection_handler_impl.cc +++ b/chromeos/ash/components/network/network_connection_handler_impl.cc
@@ -425,7 +425,8 @@ // connection. Prepare the network for connection before proceeding. cellular_connection_handler_->PrepareExistingCellularNetworkForConnection( cellular_network_iccid, - base::BindOnce(&NetworkConnectionHandlerImpl::CallShillConnect, + base::BindOnce(&NetworkConnectionHandlerImpl:: + OnPrepareCellularNetworkForConnectionSuccess, AsWeakPtr()), base::BindOnce(&NetworkConnectionHandlerImpl:: OnPrepareCellularNetworkForConnectionFailure, @@ -447,6 +448,18 @@ AsWeakPtr(), check_error_state)); } +void NetworkConnectionHandlerImpl::OnPrepareCellularNetworkForConnectionSuccess( + const std::string& service_path, + bool auto_connected) { + // If the cellular network is auto-connected by Shill, there is no need to + // call Shill connect. + if (auto_connected) { + HandleShillConnectSuccess(service_path); + return; + } + CallShillConnect(service_path); +} + void NetworkConnectionHandlerImpl::DisconnectNetwork( const std::string& service_path, base::OnceClosure success_callback,
diff --git a/chromeos/ash/components/network/network_connection_handler_impl.h b/chromeos/ash/components/network/network_connection_handler_impl.h index e51e684e..4785653 100644 --- a/chromeos/ash/components/network/network_connection_handler_impl.h +++ b/chromeos/ash/components/network/network_connection_handler_impl.h
@@ -99,6 +99,12 @@ ConnectRequest* GetPendingRequest(const std::string& service_path); bool HasPendingCellularRequest() const; + // Callback when PrepareExistingCellularNetworkForConnection succeeded. + void OnPrepareCellularNetworkForConnectionSuccess( + const std::string& service_path, + bool auto_connected); + + // Callback when PrepareExistingCellularNetworkForConnection failed. void OnPrepareCellularNetworkForConnectionFailure( const std::string& service_path, const std::string& error_name);
diff --git a/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc b/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc index 63b4dd6a..bb9eed2 100644 --- a/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc +++ b/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc
@@ -63,6 +63,7 @@ const char kTestCellularServicePath2[] = "cellular_service_path_2"; const char kTestIccid2[] = "9876543210987654321"; +constexpr base::TimeDelta kCellularAutoConnectTimeout = base::Seconds(120); class TestNetworkConnectionObserver : public NetworkConnectionObserver { public: @@ -701,7 +702,8 @@ TEST_F(NetworkConnectionHandlerImplTest, IgnoreConnectInProgressError_Fails) { Init(); - AddCellularServiceWithESimProfile(); + AddNonConnectablePSimService(); + SetCellularServiceConnectable(); SetShillConnectError(shill::kErrorResultInProgress); Connect(kTestCellularServicePath); EXPECT_TRUE(GetResultAndReset().empty()); @@ -1169,7 +1171,8 @@ EXPECT_EQ(kSuccessResult, GetResultAndReset()); } -TEST_F(NetworkConnectionHandlerImplTest, ESimProfile_EnableProfile) { +TEST_F(NetworkConnectionHandlerImplTest, + ESimProfile_EnableProfileAndWaitForAutoconnect) { Init(); AddCellularServiceWithESimProfile(); @@ -1177,6 +1180,23 @@ // connection is initiated, we attempt to enable the profile via Hermes. Connect(kTestCellularServicePath); SetCellularServiceConnectable(); + // Set cellular service to connected state. + SetCellularServiceState(shill::kStateOnline); + EXPECT_EQ(kSuccessResult, GetResultAndReset()); +} + +TEST_F(NetworkConnectionHandlerImplTest, + ESimProfile_EnableProfileAndAutoconnectTimeout) { + Init(); + AddCellularServiceWithESimProfile(); + + // Do not set the service to be connectable before trying to connect. When a + // connection is initiated, we attempt to enable the profile via Hermes. + Connect(kTestCellularServicePath); + SetCellularServiceConnectable(); + EXPECT_TRUE(GetResultAndReset().empty()); + + AdvanceClock(kCellularAutoConnectTimeout); EXPECT_EQ(kSuccessResult, GetResultAndReset()); } @@ -1191,6 +1211,8 @@ // Now, create a non-stub service and make it connectable. AddNonConnectableESimService(); SetCellularServiceConnectable(); + // Set cellular service to connected state. + SetCellularServiceState(shill::kStateOnline); EXPECT_EQ(kSuccessResult, GetResultAndReset());
diff --git a/chromeos/ash/services/assistant/public/cpp/features.cc b/chromeos/ash/services/assistant/public/cpp/features.cc index eedd46bc..7135da0 100644 --- a/chromeos/ash/services/assistant/public/cpp/features.cc +++ b/chromeos/ash/services/assistant/public/cpp/features.cc
@@ -52,7 +52,7 @@ BASE_FEATURE(kEnableLibAssistantSandbox, "LibAssistantSandbox", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kEnableLibAssistantV2, "LibAssistantV2",
diff --git a/chromeos/ash/services/cellular_setup/esim_profile.cc b/chromeos/ash/services/cellular_setup/esim_profile.cc index 7aba281..af0b11a 100644 --- a/chromeos/ash/services/cellular_setup/esim_profile.cc +++ b/chromeos/ash/services/cellular_setup/esim_profile.cc
@@ -391,7 +391,8 @@ weak_ptr_factory_.GetWeakPtr())); } -void ESimProfile::OnNewProfileEnableSuccess(const std::string& service_path) { +void ESimProfile::OnNewProfileEnableSuccess(const std::string& service_path, + bool auto_connected) { const NetworkState* network_state = esim_manager_->network_state_handler()->GetNetworkState(service_path); if (!network_state) {
diff --git a/chromeos/ash/services/cellular_setup/esim_profile.h b/chromeos/ash/services/cellular_setup/esim_profile.h index ac54149..b4961d8 100644 --- a/chromeos/ash/services/cellular_setup/esim_profile.h +++ b/chromeos/ash/services/cellular_setup/esim_profile.h
@@ -94,7 +94,8 @@ void OnPendingProfileInstallResult( std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock, HermesResponseStatus status); - void OnNewProfileEnableSuccess(const std::string& service_path); + void OnNewProfileEnableSuccess(const std::string& service_path, + bool auto_connected); void OnPrepareCellularNetworkForConnectionFailure( const std::string& service_path, const std::string& error_name);
diff --git a/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc b/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc index bb1f777..2c13dd5 100644 --- a/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc +++ b/chromeos/ash/services/cellular_setup/esim_profile_unittest.cc
@@ -139,6 +139,7 @@ })); FastForwardProfileRefreshDelay(); + FastForwardAutoConnectWaiting(); if (wait_for_connect) { base::RunLoop().RunUntilIdle();
diff --git a/chromeos/ash/services/cellular_setup/esim_test_base.cc b/chromeos/ash/services/cellular_setup/esim_test_base.cc index 527d7ca..ffb9affb 100644 --- a/chromeos/ash/services/cellular_setup/esim_test_base.cc +++ b/chromeos/ash/services/cellular_setup/esim_test_base.cc
@@ -139,4 +139,9 @@ task_environment()->FastForwardBy(2 * kProfileRefreshCallbackDelay); } +void ESimTestBase::FastForwardAutoConnectWaiting() { + task_environment_.FastForwardBy( + CellularConnectionHandler::kWaitingForAutoConnectTimeout); +} + } // namespace ash::cellular_setup
diff --git a/chromeos/ash/services/cellular_setup/esim_test_base.h b/chromeos/ash/services/cellular_setup/esim_test_base.h index f82f2b6..38aaad4 100644 --- a/chromeos/ash/services/cellular_setup/esim_test_base.h +++ b/chromeos/ash/services/cellular_setup/esim_test_base.h
@@ -52,6 +52,7 @@ ~ESimTestBase() override; void FastForwardProfileRefreshDelay(); + void FastForwardAutoConnectWaiting(); ESimManager* esim_manager() { return esim_manager_.get(); } ESimManagerTestObserver* observer() { return observer_.get(); }
diff --git a/chromeos/ash/services/cellular_setup/euicc_unittest.cc b/chromeos/ash/services/cellular_setup/euicc_unittest.cc index a33856a9..feb005d 100644 --- a/chromeos/ash/services/cellular_setup/euicc_unittest.cc +++ b/chromeos/ash/services/cellular_setup/euicc_unittest.cc
@@ -94,6 +94,7 @@ FastForwardProfileRefreshDelay(); if (wait_for_connect) { + FastForwardAutoConnectWaiting(); base::RunLoop().RunUntilIdle(); EXPECT_LE(1u, network_connection_handler()->connect_calls().size()); if (fail_connect) {
diff --git a/chromeos/ash/services/device_sync/BUILD.gn b/chromeos/ash/services/device_sync/BUILD.gn index 13d0ae6..5a3a817 100644 --- a/chromeos/ash/services/device_sync/BUILD.gn +++ b/chromeos/ash/services/device_sync/BUILD.gn
@@ -11,7 +11,10 @@ } static_library("group_private_key_and_better_together_metadata_status") { - sources = [ "group_private_key_and_better_together_metadata_status.h" ] + sources = [ + "group_private_key_and_better_together_metadata_status.cc", + "group_private_key_and_better_together_metadata_status.h", + ] } static_library("device_sync") {
diff --git a/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.cc b/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.cc new file mode 100644 index 0000000..e9944997 --- /dev/null +++ b/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.cc
@@ -0,0 +1,83 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h" + +namespace { + +constexpr char private_key_status_prefix[] = + "[DeviceSyncer group private key status: "; +constexpr char better_together_metadata_status_prefix[] = + "[DeviceSyncer better together metadata status: "; + +} // namespace + +namespace ash::device_sync { + +std::ostream& operator<<(std::ostream& stream, + const GroupPrivateKeyStatus& status) { + switch (status) { + case GroupPrivateKeyStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized: + stream << private_key_status_prefix + << "Status unavailable because device sync is not initialized]"; + break; + case GroupPrivateKeyStatus::kWaitingForGroupPrivateKey: + stream << private_key_status_prefix + << "Waiting to receive group private key]"; + break; + case GroupPrivateKeyStatus::kNoEncryptedGroupPrivateKeyReceived: + stream << private_key_status_prefix + << "No encrypted group private key received]"; + break; + case GroupPrivateKeyStatus::kEncryptedGroupPrivateKeyEmpty: + stream << private_key_status_prefix + << "Encrypted group private key empty]"; + break; + case GroupPrivateKeyStatus::kLocalDeviceSyncBetterTogetherKeyMissing: + stream << private_key_status_prefix + << "Local device sync better together key missing]"; + break; + case GroupPrivateKeyStatus::kGroupPrivateKeyDecryptionFailed: + stream << private_key_status_prefix + << "Group private key decryption failed]"; + break; + case GroupPrivateKeyStatus::kGroupPrivateKeySuccessfullyDecrypted: + stream << private_key_status_prefix + << "Group private key successfully decrypted]"; + break; + } + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, + const BetterTogetherMetadataStatus& status) { + switch (status) { + case BetterTogetherMetadataStatus:: + kStatusUnavailableBecauseDeviceSyncIsNotInitialized: + stream << better_together_metadata_status_prefix + << "Status unavailable because device sync is not initialized]"; + break; + case BetterTogetherMetadataStatus::kWaitingToProcessDeviceMetadata: + stream << better_together_metadata_status_prefix + << "Waiting to process device metadata]"; + break; + case BetterTogetherMetadataStatus::kGroupPrivateKeyMissing: + stream << better_together_metadata_status_prefix + << "Group private key is missing]"; + break; + case BetterTogetherMetadataStatus::kEncryptedMetadataEmpty: + stream << better_together_metadata_status_prefix + << "Encrypted metadata is empty]"; + break; + case BetterTogetherMetadataStatus::kMetadataDecrypted: + stream << better_together_metadata_status_prefix << "Metadata decrypted]"; + break; + } + + return stream; +} + +} // namespace ash::device_sync \ No newline at end of file
diff --git a/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h b/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h index 0f0f838a..7986612 100644 --- a/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h +++ b/chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h
@@ -5,6 +5,8 @@ #ifndef CHROMEOS_ASH_SERVICES_DEVICE_SYNC_GROUP_PRIVATE_KEY_AND_BETTER_TOGETHER_METADATA_STATUS_H_ #define CHROMEOS_ASH_SERVICES_DEVICE_SYNC_GROUP_PRIVATE_KEY_AND_BETTER_TOGETHER_METADATA_STATUS_H_ +#include <ostream> + namespace ash::device_sync { // The group private key and better together metadata status in the @@ -63,6 +65,11 @@ kMetadataDecrypted, }; +std::ostream& operator<<(std::ostream& stream, + const GroupPrivateKeyStatus& state); +std::ostream& operator<<(std::ostream& stream, + const BetterTogetherMetadataStatus& state); + } // namespace ash::device_sync #endif // CHROMEOS_ASH_SERVICES_DEVICE_SYNC_GROUP_PRIVATE_KEY_AND_BETTER_TOGETHER_METADATA_STATUS_H_
diff --git a/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.cc b/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.cc index edcc4c1b..747620b7 100644 --- a/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.cc +++ b/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.cc
@@ -158,6 +158,15 @@ return force_sync_now_callback_queue_.size(); } +int FakeDeviceSyncClient::GetBetterTogetherMetadataStatusCallbackQueueSize() + const { + return get_better_together_metadata_status_callback_queue_.size(); +} + +int FakeDeviceSyncClient::GetGroupPrivateKeyStatusCallbackQueueSize() const { + return get_group_private_key_status_callback_queue_.size(); +} + int FakeDeviceSyncClient::GetSetSoftwareFeatureStateInputsQueueSize() const { return set_software_feature_state_inputs_queue_.size(); } @@ -191,6 +200,21 @@ force_sync_now_callback_queue_.pop_front(); } +void FakeDeviceSyncClient::InvokePendingGetBetterTogetherMetadataStatusCallback( + BetterTogetherMetadataStatus status) { + DCHECK(get_better_together_metadata_status_callback_queue_.size() > 0); + std::move(get_better_together_metadata_status_callback_queue_.front()) + .Run(status); + get_better_together_metadata_status_callback_queue_.pop_front(); +} + +void FakeDeviceSyncClient::InvokePendingGetGroupPrivateKeyStatusCallback( + GroupPrivateKeyStatus status) { + DCHECK(get_group_private_key_status_callback_queue_.size() > 0); + std::move(get_group_private_key_status_callback_queue_.front()).Run(status); + get_group_private_key_status_callback_queue_.pop_front(); +} + void FakeDeviceSyncClient::InvokePendingSetSoftwareFeatureStateCallback( mojom::NetworkRequestResult result_code) { DCHECK(set_software_feature_state_inputs_queue_.size() > 0);
diff --git a/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.h b/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.h index 8b80f617..404cc1f 100644 --- a/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.h +++ b/chromeos/ash/services/device_sync/public/cpp/fake_device_sync_client.h
@@ -14,6 +14,7 @@ #include "chromeos/ash/components/multidevice/remote_device_ref.h" #include "chromeos/ash/components/multidevice/software_feature.h" #include "chromeos/ash/services/device_sync/feature_status_change.h" +#include "chromeos/ash/services/device_sync/group_private_key_and_better_together_metadata_status.h" #include "chromeos/ash/services/device_sync/proto/cryptauth_common.pb.h" #include "chromeos/ash/services/device_sync/public/cpp/device_sync_client.h" #include "chromeos/ash/services/device_sync/public/mojom/device_sync.mojom.h" @@ -111,6 +112,8 @@ int GetForceEnrollmentNowCallbackQueueSize() const; int GetForceSyncNowCallbackQueueSize() const; + int GetBetterTogetherMetadataStatusCallbackQueueSize() const; + int GetGroupPrivateKeyStatusCallbackQueueSize() const; int GetSetSoftwareFeatureStateInputsQueueSize() const; int GetSetFeatureStatusInputsQueueSize() const; int GetFindEligibleDevicesInputsQueueSize() const; @@ -119,6 +122,10 @@ void InvokePendingForceEnrollmentNowCallback(bool success); void InvokePendingForceSyncNowCallback(bool success); + void InvokePendingGetBetterTogetherMetadataStatusCallback( + BetterTogetherMetadataStatus status); + void InvokePendingGetGroupPrivateKeyStatusCallback( + GroupPrivateKeyStatus status); void InvokePendingSetSoftwareFeatureStateCallback( mojom::NetworkRequestResult result_code); void InvokePendingSetFeatureStatusCallback(
diff --git a/chromeos/ash/services/libassistant/BUILD.gn b/chromeos/ash/services/libassistant/BUILD.gn index ef7197a..a67bf43 100644 --- a/chromeos/ash/services/libassistant/BUILD.gn +++ b/chromeos/ash/services/libassistant/BUILD.gn
@@ -84,6 +84,7 @@ ":constants", ":loader", "//base", + "//chromeos/ash/services/assistant/public/cpp", "//chromeos/assistant/internal:internal", "//sandbox/linux:sandbox_services", "//sandbox/policy",
diff --git a/chromeos/ash/services/libassistant/libassistant_sandbox_hook.cc b/chromeos/ash/services/libassistant/libassistant_sandbox_hook.cc index 54abe2dd..36063be 100644 --- a/chromeos/ash/services/libassistant/libassistant_sandbox_hook.cc +++ b/chromeos/ash/services/libassistant/libassistant_sandbox_hook.cc
@@ -7,6 +7,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/system/sys_info.h" +#include "chromeos/ash/services/assistant/public/cpp/features.h" #include "chromeos/ash/services/libassistant/constants.h" #include "chromeos/ash/services/libassistant/libassistant_loader_impl.h" #include "chromeos/assistant/internal/libassistant_util.h" @@ -66,7 +67,10 @@ bool LibassistantPreSandboxHook( sandbox::policy::SandboxLinux::Options options) { // Load libassistant DLC before the sandbox initializes. - LibassistantLoaderImpl::GetInstance()->LoadBlocking(kLibAssistantDlcRootPath); + if (assistant::features::IsLibAssistantDlcEnabled()) { + LibassistantLoaderImpl::GetInstance()->LoadBlocking( + kLibAssistantDlcRootPath); + } auto* instance = sandbox::policy::SandboxLinux::GetInstance(); instance->StartBrokerProcess(
diff --git a/components/autofill/core/browser/autofill_merge_unittest.cc b/components/autofill/core/browser/autofill_merge_unittest.cc index 1685470..732c7737 100644 --- a/components/autofill/core/browser/autofill_merge_unittest.cc +++ b/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -286,16 +286,16 @@ field->set_heuristic_type(GetActivePatternSource(), type); } - // Import the profile. - auto imported_data = form_data_importer_->ImportFormData( + // Extract the profile. + auto extracted_data = form_data_importer_->ExtractFormData( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); form_data_importer_->ProcessAddressProfileImportCandidates( - imported_data.address_profile_import_candidates, + extracted_data.address_profile_import_candidates, /*allow_prompt=*/true); - EXPECT_FALSE(imported_data.credit_card_import_candidate); - EXPECT_FALSE(imported_data.imported_upi_id.has_value()); + EXPECT_FALSE(extracted_data.credit_card_import_candidate); + EXPECT_FALSE(extracted_data.extracted_upi_id.has_value()); // Clear the |form| to start a new profile. form.fields.clear();
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index 3630f29..ab55ba3 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -122,16 +122,16 @@ } // namespace -FormDataImporter::ImportFormDataResult::ImportFormDataResult() = default; +FormDataImporter::ExtractedFormData::ExtractedFormData() = default; -FormDataImporter::ImportFormDataResult::ImportFormDataResult( - const ImportFormDataResult& imported_form_data) = default; +FormDataImporter::ExtractedFormData::ExtractedFormData( + const ExtractedFormData& extracted_form_data) = default; -FormDataImporter::ImportFormDataResult& -FormDataImporter::ImportFormDataResult::operator=( - const ImportFormDataResult& imported_form_data) = default; +FormDataImporter::ExtractedFormData& +FormDataImporter::ExtractedFormData::operator=( + const ExtractedFormData& extracted_form_data) = default; -FormDataImporter::ImportFormDataResult::~ImportFormDataResult() = default; +FormDataImporter::ExtractedFormData::~ExtractedFormData() = default; FormDataImporter::FormDataImporter(AutofillClient* client, payments::PaymentsClient* payments_client, @@ -187,16 +187,16 @@ const FormStructure& submitted_form, bool profile_autofill_enabled, bool payment_methods_autofill_enabled) { - ImportFormDataResult imported_data = - ImportFormData(submitted_form, profile_autofill_enabled, - payment_methods_autofill_enabled); + ExtractedFormData extracted_data = + ExtractFormData(submitted_form, profile_autofill_enabled, + payment_methods_autofill_enabled); // Create a vector of address profile import candidates. // This is used to make preliminarily imported profiles available // to the credit card import logic. std::vector<AutofillProfile> preliminary_imported_address_profiles; for (const auto& candidate : - imported_data.address_profile_import_candidates) { + extracted_data.address_profile_import_candidates) { if (candidate.all_requirements_fulfilled) preliminary_imported_address_profiles.push_back(candidate.profile); } @@ -204,22 +204,22 @@ preliminary_imported_address_profiles); bool cc_prompt_potentially_shown = ProcessCreditCardImportCandidate( - submitted_form, imported_data.credit_card_import_candidate, - imported_data.imported_upi_id, payment_methods_autofill_enabled, + submitted_form, extracted_data.credit_card_import_candidate, + extracted_data.extracted_upi_id, payment_methods_autofill_enabled, credit_card_save_manager_->IsCreditCardUploadEnabled()); fetched_card_instrument_id_.reset(); bool iban_prompt_potentially_shown = false; - if (imported_data.iban_import_candidate.has_value() && + if (extracted_data.iban_import_candidate.has_value() && payment_methods_autofill_enabled) { iban_prompt_potentially_shown = - ProcessIBANImportCandidate(*imported_data.iban_import_candidate); + ProcessIBANImportCandidate(*extracted_data.iban_import_candidate); } // If a prompt for credit cards or IBANs is potentially shown, do not allow // for a second address profile import dialog. ProcessAddressProfileImportCandidates( - imported_data.address_profile_import_candidates, + extracted_data.address_profile_import_candidates, !cc_prompt_potentially_shown && !iban_prompt_potentially_shown); } @@ -273,38 +273,40 @@ fetched_card_instrument_id_ = instrument_id; } -FormDataImporter::ImportFormDataResult FormDataImporter::ImportFormData( +FormDataImporter::ExtractedFormData FormDataImporter::ExtractFormData( const FormStructure& submitted_form, bool profile_autofill_enabled, bool payment_methods_autofill_enabled) { - ImportFormDataResult imported_form_data; + ExtractedFormData extracted_form_data; // We try the same `form` for both credit card and address import/update. - // - `ImportCreditCard()` may update an existing card, or fill - // `credit_card_import_candidate` contained in `imported_form_data` with an + // - `ExtractCreditCard()` may update an existing card, or fill + // `credit_card_import_candidate` contained in `extracted_form_data` with an // extracted card. - // - `ImportAddressProfiles()` collects all importable profiles, but currently + // - `ExtractAddressProfiles()` collects all importable + // profiles, but currently // at most one import prompt is shown. - // Reset `imported_credit_card_record_type_` every time we import data from - // form no matter whether `ImportCreditCard()` is called or not. - imported_credit_card_record_type_ = ImportedCreditCardRecordType::kNoCard; + // Reset `credit_card_import_type_` every time we extract + // data from form no matter whether `ExtractCreditCard()` is + // called or not. + credit_card_import_type_ = CreditCardImportType::kNoCard; if (payment_methods_autofill_enabled) { - imported_form_data.credit_card_import_candidate = - ImportCreditCard(submitted_form); - imported_form_data.imported_upi_id = ImportUpiId(submitted_form); + extracted_form_data.credit_card_import_candidate = + ExtractCreditCard(submitted_form); + extracted_form_data.extracted_upi_id = ExtractUpiId(submitted_form); } #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) if (base::FeatureList::IsEnabled(features::kAutofillFillIbanFields) && payment_methods_autofill_enabled) { - imported_form_data.iban_import_candidate = ImportIBAN(submitted_form); + extracted_form_data.iban_import_candidate = ExtractIBAN(submitted_form); } #endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) size_t num_complete_address_profiles = 0; if (profile_autofill_enabled && !base::FeatureList::IsEnabled(features::kAutofillDisableAddressImport)) { - num_complete_address_profiles = ImportAddressProfiles( - submitted_form, &imported_form_data.address_profile_import_candidates); + num_complete_address_profiles = ExtractAddressProfiles( + submitted_form, &extracted_form_data.address_profile_import_candidates); } if (profile_autofill_enabled && payment_methods_autofill_enabled && @@ -317,24 +319,24 @@ form_associator_.TrackFormAssociations( origin, form_signature, FormAssociator::FormType::kAddressForm); } - if (imported_form_data.credit_card_import_candidate) { + if (extracted_form_data.credit_card_import_candidate) { form_associator_.TrackFormAssociations( origin, form_signature, FormAssociator::FormType::kCreditCardForm); } } - if (!imported_form_data.credit_card_import_candidate && - !imported_form_data.imported_upi_id && + if (!extracted_form_data.credit_card_import_candidate && + !extracted_form_data.extracted_upi_id && num_complete_address_profiles == 0 && - (!imported_form_data.iban_import_candidate || - imported_form_data.iban_import_candidate->record_type() != + (!extracted_form_data.iban_import_candidate || + extracted_form_data.iban_import_candidate->record_type() != IBAN::NEW_IBAN)) { personal_data_manager_->MarkObserversInsufficientFormDataForImport(); } - return imported_form_data; + return extracted_form_data; } -size_t FormDataImporter::ImportAddressProfiles( +size_t FormDataImporter::ExtractAddressProfiles( const FormStructure& form, std::vector<FormDataImporter::AddressProfileImportCandidate>* address_profile_import_candidates) { @@ -371,25 +373,26 @@ LOG_AF(import_log_buffer) << LogMessage::kImportAddressProfileFromFormSection << section << CTag{}; - // Try to import an address profile from the form fields of this section. + // Try to extract an address profile from the form fields of this section. // Only allow for a prompt if no other complete profile was found so far. - if (ImportAddressProfileForSection(form, section, - address_profile_import_candidates, - &import_log_buffer)) + if (ExtractAddressProfileFromSection(form, section, + address_profile_import_candidates, + &import_log_buffer)) { num_complete_profiles++; + } // And close the div of the section import log. LOG_AF(import_log_buffer) << CTag{"div"}; } - // Run the import on the union of the section if the import was not + // Run the extract on the union of the section if the import was not // successful and if there is more than one section. if (num_complete_profiles > 0) { AutofillMetrics::LogAddressFormImportStatusMetric( AutofillMetrics::AddressProfileImportStatusMetric::REGULAR_IMPORT); } else if (sections.size() > 1) { - // Try to import by combining all sections. - if (ImportAddressProfileForSection(form, absl::nullopt, - address_profile_import_candidates, - &import_log_buffer)) { + // Try to extract by combining all sections. + if (ExtractAddressProfileFromSection(form, absl::nullopt, + address_profile_import_candidates, + &import_log_buffer)) { num_complete_profiles++; AutofillMetrics::LogAddressFormImportStatusMetric( AutofillMetrics::AddressProfileImportStatusMetric:: @@ -411,7 +414,7 @@ return num_complete_profiles; } -bool FormDataImporter::ImportAddressProfileForSection( +bool FormDataImporter::ExtractAddressProfileFromSection( const FormStructure& form, const absl::optional<Section>& section, std::vector<FormDataImporter::AddressProfileImportCandidate>* @@ -466,7 +469,7 @@ AutofillType field_type = field->Type(); - // Credit card fields are handled by ImportCreditCard(). + // Credit card fields are handled by ExtractCreditCard(). if (field_type.group() == FieldTypeGroup::kCreditCard) continue; @@ -728,18 +731,17 @@ bool FormDataImporter::ProcessCreditCardImportCandidate( const FormStructure& submitted_form, const absl::optional<CreditCard>& credit_card_import_candidate, - const absl::optional<std::string>& imported_upi_id, + const absl::optional<std::string>& extracted_upi_id, bool payment_methods_autofill_enabled, bool is_credit_card_upstream_enabled) { #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - if (imported_upi_id && payment_methods_autofill_enabled && + if (extracted_upi_id && payment_methods_autofill_enabled && base::FeatureList::IsEnabled(features::kAutofillSaveAndFillVPA)) { - upi_vpa_save_manager_->OfferLocalSave(*imported_upi_id); + upi_vpa_save_manager_->OfferLocalSave(*extracted_upi_id); } #endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // If no card was successfully imported from the form, return. - if (imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kNoCard) { + // If no card was successfully extracted from the form, return. + if (credit_card_import_type_ == CreditCardImportType::kNoCard) { return false; } // Do not offer upload save for google domain. @@ -757,12 +759,12 @@ } #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // A credit card was successfully imported, but it's possible it is already a + // A credit card was successfully extracted, but it's possible it is already a // local or server card. First, check to see if we should offer local card // migration in this case, as local cards could go either way. if (local_card_migration_manager_ && local_card_migration_manager_->ShouldOfferLocalCardMigration( - credit_card_import_candidate, imported_credit_card_record_type_)) { + credit_card_import_candidate, credit_card_import_type_)) { local_card_migration_manager_->AttemptToOfferLocalCardMigration( /*is_from_settings_page=*/false); return true; @@ -780,25 +782,22 @@ // We have a card to save; decide what type of save flow to display. if (is_credit_card_upstream_enabled) { // Attempt to offer upload save. Because we pass - // |credit_card_upstream_enabled| to ImportFormData, this block can be - // reached on observing either a new card or one already stored locally - // which doesn't match an existing server card. If Google Payments declines - // allowing upload, |credit_card_save_manager_| is tasked with deciding if - // we should fall back to local save or not. - DCHECK(imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kLocalCard || - imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kNewCard); + // `credit_card_upstream_enabled` to ExtractFormImportCandidates, this block + // can be reached on observing either a new card or one already stored + // locally which doesn't match an existing server card. If Google Payments + // declines allowing upload, `credit_card_save_manager_` is tasked with + // deciding if we should fall back to local save or not. + DCHECK(credit_card_import_type_ == CreditCardImportType::kLocalCard || + credit_card_import_type_ == CreditCardImportType::kNewCard); credit_card_save_manager_->AttemptToOfferCardUploadSave( submitted_form, from_dynamic_change_form_, has_non_focusable_field_, *credit_card_import_candidate, - /*uploading_local_card=*/imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kLocalCard); + /*uploading_local_card=*/credit_card_import_type_ == + CreditCardImportType::kLocalCard); return true; }; // If upload save is not allowed, new cards should be saved locally. - DCHECK(imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kNewCard); + DCHECK(credit_card_import_type_ == CreditCardImportType::kNewCard); if (credit_card_save_manager_->AttemptToOfferCardLocalSave( from_dynamic_change_form_, has_non_focusable_field_, *credit_card_import_candidate)) { @@ -821,7 +820,7 @@ return false; } -absl::optional<CreditCard> FormDataImporter::ImportCreditCard( +absl::optional<CreditCard> FormDataImporter::ExtractCreditCard( const FormStructure& form) { // The candidate for credit card import. There are many ways for the candidate // to be rejected as indicated by the `return absl::nullopt` statements below. @@ -856,7 +855,7 @@ // Can import one valid card per form. Start by treating it as kNewCard, but // overwrite this type if we discover it is already a local or server card. - imported_credit_card_record_type_ = ImportedCreditCardRecordType::kNewCard; + credit_card_import_type_ = CreditCardImportType::kNewCard; // Attempt to merge with an existing local credit card without presenting a // prompt. @@ -867,8 +866,7 @@ CreditCard maybe_updated_card = *local_card; if (maybe_updated_card.UpdateFromImportedCard(candidate, app_locale_)) { personal_data_manager_->UpdateCreditCard(maybe_updated_card); - imported_credit_card_record_type_ = - ImportedCreditCardRecordType::kLocalCard; + credit_card_import_type_ = CreditCardImportType::kLocalCard; if (!maybe_updated_card.nickname().empty()) { // The nickname may be shown in the upload save bubble. candidate.SetNickname(maybe_updated_card.nickname()); @@ -900,7 +898,7 @@ if (candidate.expiration_month() == 0 || candidate.expiration_year() == 0) return absl::nullopt; - imported_credit_card_record_type_ = ImportedCreditCardRecordType::kServerCard; + credit_card_import_type_ = CreditCardImportType::kServerCard; if (candidate.expiration_month() == server_card->expiration_month() && candidate.expiration_year() == server_card->expiration_year()) { @@ -919,7 +917,7 @@ return server_card; } -absl::optional<IBAN> FormDataImporter::ImportIBAN(const FormStructure& form) { +absl::optional<IBAN> FormDataImporter::ExtractIBAN(const FormStructure& form) { IBAN candidate_iban = ExtractIBANFromForm(form); if (candidate_iban.value().empty()) return absl::nullopt; @@ -1018,7 +1016,7 @@ return candidate_iban; } -absl::optional<std::string> FormDataImporter::ImportUpiId( +absl::optional<std::string> FormDataImporter::ExtractUpiId( const FormStructure& form) { for (const auto& field : form) { if (IsUPIVirtualPaymentAddress(field->value)) @@ -1037,8 +1035,7 @@ return false; // We do not want to offer upload save or local card save for server cards. - if (imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kServerCard) { + if (credit_card_import_type_ == CreditCardImportType::kServerCard) { return false; } @@ -1046,8 +1043,7 @@ // want to offer upload save as it is disabled and we do not want to offer // local card save as it is already saved as a local card. if (!is_credit_card_upload_enabled && - imported_credit_card_record_type_ == - ImportedCreditCardRecordType::kLocalCard) { + credit_card_import_type_ == CreditCardImportType::kLocalCard) { return false; }
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index 5e9a8d6..b070305f 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -37,8 +37,9 @@ // Owned by `ChromeAutofillClient`. class FormDataImporter : public PersonalDataManagerObserver { public: - // Record type of the credit card imported from the form, if one exists. - enum ImportedCreditCardRecordType { + // Record type of the credit card import candidate extracted from the form, if + // one exists. + enum CreditCardImportType { // No card was successfully imported from the form. kNoCard, // The imported card is already stored locally on the device. @@ -121,13 +122,12 @@ return form_associator_.GetFormAssociations(form_signature); } - ImportedCreditCardRecordType imported_credit_card_record_type_for_testing() - const { - return imported_credit_card_record_type_; + CreditCardImportType credit_card_import_type_for_testing() const { + return credit_card_import_type_; } - void set_imported_credit_card_record_type_for_testing( - ImportedCreditCardRecordType imported_credit_card_record_type) { - imported_credit_card_record_type_ = imported_credit_card_record_type; + void set_credit_card_import_type_for_testing( + CreditCardImportType credit_card_import_type) { + credit_card_import_type_ = credit_card_import_type; } protected: @@ -171,50 +171,50 @@ ProfileImportMetadata import_metadata; }; - // Defines data imported from the form. - struct ImportFormDataResult { - ImportFormDataResult(); - ImportFormDataResult(const ImportFormDataResult& imported_form_data); - ImportFormDataResult& operator=( - const ImportFormDataResult& imported_form_data); - ~ImportFormDataResult(); + // Defines data extracted from the form. + struct ExtractedFormData { + ExtractedFormData(); + ExtractedFormData(const ExtractedFormData& extracted_form_data); + ExtractedFormData& operator=(const ExtractedFormData& extracted_form_data); + ~ExtractedFormData(); // Credit card extracted from the form, which is a candidate for importing. // This credit card will be present after extraction if the form contained a // valid credit card, and the preconditions for extracting the credit card - // were met. See ImportCreditCard() for details on when + // were met. See `ExtractCreditCard()` for details on when // the preconditions are met for extracting a credit card from a form. absl::optional<CreditCard> credit_card_import_candidate; - // List of address profiles which are candidates for importing. The list is - // empty if none of the address profile fulfill import requirements. + // List of address profiles extracted from the form, which are candidates + // for importing. The list is empty if none of the address profile fulfill + // import requirements. std::vector<AddressProfileImportCandidate> address_profile_import_candidates; // IBAN extracted from the form, which is a candidate for importing. Present // if an IBAN is found in the form. absl::optional<IBAN> iban_import_candidate; // Present if a UPI (Unified Payment Interface) ID is found in the form. - absl::optional<std::string> imported_upi_id; + absl::optional<std::string> extracted_upi_id; }; - // Scans the given `form` for importable Autofill data. - ImportFormDataResult ImportFormData(const FormStructure& form, - bool profile_autofill_enabled, - bool payment_methods_autofill_enabled); + // Scans the given `form` for extractable Autofill data. + ExtractedFormData ExtractFormData(const FormStructure& form, + bool profile_autofill_enabled, + bool payment_methods_autofill_enabled); // Attempts to construct AddressProfileImportCandidates by extracting values - // from the fields in the |form|'s sections. Extraction can fail if the + // from the fields in the `form`'s sections. Extraction can fail if the // fields' values don't pass validation. Apart from complete address profiles, // partial profiles for silent updates are extracted. All are stored in - // |imported_form_data|'s |address_profile_import_candidates|. + // `extracted_form_data`'s `address_profile_import_candidates`. // The function returns the number of _complete_ extracted profiles. - size_t ImportAddressProfiles(const FormStructure& form, - std::vector<AddressProfileImportCandidate>* - address_profile_import_candidates); + size_t ExtractAddressProfiles(const FormStructure& form, + std::vector<AddressProfileImportCandidate>* + address_profile_import_candidates); // Helper method for ImportAddressProfiles which only considers the fields for - // a specified |section|. If no section is passed, the import is performed on + // a specified `section`. If no section is passed, the import is performed on // the union of all sections. - bool ImportAddressProfileForSection( + bool ExtractAddressProfileFromSection( const FormStructure& form, const absl::optional<Section>& section, std::vector<AddressProfileImportCandidate>* @@ -235,11 +235,11 @@ // The function has two side-effects: // - all matching local cards are updated to include the information from the // extracted card; - // - `imported_credit_card_record_type_` is set to + // - `credit_card_import_type_` is set to // - SERVER_CARD if a server card matches; // - LOCAL_CARD if a local and no server card matches; // - NEW_CARD otherwise. - absl::optional<CreditCard> ImportCreditCard(const FormStructure& form); + absl::optional<CreditCard> ExtractCreditCard(const FormStructure& form); // Returns the extracted IBAN from the `form` if applicable. // This is the case if it is a new IBAN or a local IBAN. @@ -248,17 +248,17 @@ // - record_type of the returned IBAN is set to // - LOCAL_IBAN if a local IBAN matches; // - NEW_IBAN if no local IBAN matches - absl::optional<IBAN> ImportIBAN(const FormStructure& form); + absl::optional<IBAN> ExtractIBAN(const FormStructure& form); // Tries to initiate the saving of the `credit_card_import_candidate` // if applicable. `submitted_form` is the form from which the card was - // imported. If a UPI id was found it is stored in `imported_upi_id`. + // imported. If a UPI id was found it is stored in `extracted_upi_id`. // `is_credit_card_upstream_enabled` indicates if server card storage is // enabled. Returns true if a save is initiated. bool ProcessCreditCardImportCandidate( const FormStructure& submitted_form, const absl::optional<CreditCard>& credit_card_import_candidate, - const absl::optional<std::string>& imported_upi_id, + const absl::optional<std::string>& extracted_upi_id, bool payment_methods_autofill_enabled, bool is_credit_card_upstream_enabled); @@ -274,9 +274,9 @@ // Extracts the IBAN from the form structure. IBAN ExtractIBANFromForm(const FormStructure& form); - // Go through the |form| fields and find a UPI ID to import. The return value + // Go through the `form` fields and find a UPI ID to extract. The return value // will be empty if no UPI ID was found. - absl::optional<std::string> ImportUpiId(const FormStructure& form); + absl::optional<std::string> ExtractUpiId(const FormStructure& form); // Returns true if credit card upload or local save should be offered to user. // |credit_card_import_candidate| is the credit card imported from the form if @@ -342,11 +342,11 @@ // May be NULL. NULL indicates OTR. raw_ptr<PersonalDataManager> personal_data_manager_; - // Represents the type of the imported credit card from the submitted form. - // It will be used to determine whether to offer upload save or card - // migration. Will be passed to `credit_card_save_manager_` for metrics. - ImportedCreditCardRecordType imported_credit_card_record_type_ = - ImportedCreditCardRecordType::kNoCard; + // Represents the type of the credit card import candidate from the submitted + // form. It will be used to determine whether to offer upload save or card + // migration. Will be passed to `credit_card_save_manager_` for metrics. If no + // credit card was found in the form, the type will be `kNoCard`. + CreditCardImportType credit_card_import_type_ = CreditCardImportType::kNoCard; std::string app_locale_;
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index ff9b84c..027b224 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -481,7 +481,7 @@ class FormDataImporterTestBase { public: - using ImportFormDataResult = FormDataImporter::ImportFormDataResult; + using ExtractedFormData = FormDataImporter::ExtractedFormData; using AddressProfileImportCandidate = FormDataImporter::AddressProfileImportCandidate; @@ -609,16 +609,16 @@ // Helper methods that simply forward the call to the private member (to avoid // having to friend every test that needs to access the private - // PersonalDataManager::ImportAddressProfile or ImportCreditCard). - void ImportAddressProfiles(bool extraction_successful, - const FormStructure& form, - bool skip_waiting_on_pdm = false, - bool allow_save_prompts = true) { + // PersonalDataManager::ImportAddressProfile or ExtractCreditCard). + void ExtractAddressProfiles(bool extraction_successful, + const FormStructure& form, + bool skip_waiting_on_pdm = false, + bool allow_save_prompts = true) { std::vector<FormDataImporter::AddressProfileImportCandidate> address_profile_import_candidates; EXPECT_EQ(extraction_successful, - form_data_importer().ImportAddressProfiles( + form_data_importer().ExtractAddressProfiles( form, &address_profile_import_candidates) > 0); if (!extraction_successful) { @@ -645,70 +645,72 @@ } // Verifies that the stored profiles in the PersonalDataManager equal - // |expected_profiles| with respect to |AutofillProfile::Compare|. + // `expected_profiles` with respect to `AutofillProfile::Compare`. // Note, that order is taken into account. - void VerifyExpectationForImportedAddressProfiles( + void VerifyExpectationForExtractedAddressProfiles( const std::vector<AutofillProfile>& expected_profiles) { EXPECT_THAT(personal_data_manager_->GetProfiles(), UnorderedElementsCompareEqualArray(expected_profiles)); } - // Convenience wrapper that calls |FormDataImporter::ImportFormData()| and - // subsequently processes the candidates for address profile import. - // Returns the result of |FormDataImporter::ImportFormData()|. - ImportFormDataResult ImportFormDataAndProcessAddressCandidates( + // Convenience wrapper that calls + // `FormDataImporter::ExtractFormData()` and subsequently + // processes the candidates for address profile import. Returns the result of + // `FormDataImporter::ExtractFormData()`. + ExtractedFormData ExtractFormDataAndProcessAddressCandidates( const FormStructure& form, bool profile_autofill_enabled, bool payment_methods_autofill_enabled) { - ImportFormDataResult imported_data = form_data_importer().ImportFormData( + ExtractedFormData extracted_data = form_data_importer().ExtractFormData( form, profile_autofill_enabled, payment_methods_autofill_enabled); form_data_importer().ProcessAddressProfileImportCandidates( - imported_data.address_profile_import_candidates); - return imported_data; + extracted_data.address_profile_import_candidates); + return extracted_data; } - // Convenience wrapper around `ImportFormDataAndProcessAddressCandidates()`. - void ImportFormDataAndProcessAddressCandidates(const FormStructure& form) { - std::ignore = ImportFormDataAndProcessAddressCandidates( + // Convenience wrapper around `ExtractFormDataAndProcessAddressCandidates()`. + void ExtractFormDataAndProcessAddressCandidates(const FormStructure& form) { + std::ignore = ExtractFormDataAndProcessAddressCandidates( form, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); } - // Convenience wrapper that calls `FormDataImporter::ImportFormData()` and - // subsequently processes the candidates for IBAN import candidate. - // Returns the result of `FormDataImporter::ProcessIBANImportCandidate()`. - bool ImportFormDataAndProcessIBANCandidates( + // Convenience wrapper that calls + // `FormDataImporter::ExtractFormData()` and subsequently + // processes the candidates for IBAN import candidate. Returns the result of + // `FormDataImporter::ProcessIBANImportCandidate()`. + bool ExtractFormDataAndProcessIBANCandidates( const FormStructure& form, bool profile_autofill_enabled, bool payment_methods_autofill_enabled) { - ImportFormDataResult imported_data = form_data_importer().ImportFormData( + ExtractedFormData extracted_data = form_data_importer().ExtractFormData( form, profile_autofill_enabled, payment_methods_autofill_enabled); - return imported_data.iban_import_candidate && + return extracted_data.iban_import_candidate && form_data_importer().ProcessIBANImportCandidate( - imported_data.iban_import_candidate.value()); + extracted_data.iban_import_candidate.value()); } - void ImportAddressProfilesAndVerifyExpectation( + void ExtractAddressProfilesAndVerifyExpectation( const FormStructure& form, const std::vector<AutofillProfile>& expected_profiles) { - ImportAddressProfiles(/*extraction_successful=*/!expected_profiles.empty(), - form); - VerifyExpectationForImportedAddressProfiles(expected_profiles); + ExtractAddressProfiles( + /*extraction_successful=*/!expected_profiles.empty(), form); + VerifyExpectationForExtractedAddressProfiles(expected_profiles); } - void ImportAddressProfileAndVerifyImportOfDefaultProfile( + void ExtractAddressProfileAndVerifyExtractionOfDefaultProfile( const FormStructure& form) { - ImportAddressProfilesAndVerifyExpectation(form, - {ConstructDefaultProfile()}); + ExtractAddressProfilesAndVerifyExpectation(form, + {ConstructDefaultProfile()}); } void ImportAddressProfileAndVerifyImportOfNoProfile( const FormStructure& form) { - ImportAddressProfilesAndVerifyExpectation(form, {}); + ExtractAddressProfilesAndVerifyExpectation(form, {}); } - absl::optional<CreditCard> ImportCreditCard(const FormStructure& form) { - return form_data_importer().ImportCreditCard(form); + absl::optional<CreditCard> ExtractCreditCard(const FormStructure& form) { + return form_data_importer().ExtractCreditCard(form); } void SubmitFormAndExpectImportedCardWithData(const FormData& form, @@ -719,7 +721,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate); @@ -769,7 +771,7 @@ std::tuple<AutofillEnableSupportForApartmentNumbers, AutofillFillIbanFields>> { public: - using ImportFormDataResult = FormDataImporter::ImportFormDataResult; + using ExtractedFormData = FormDataImporter::ExtractedFormData; private: void SetUp() override { @@ -805,8 +807,8 @@ ConstructFormStructureFromTypeValuePairs( GetDefaultProfileTypeValuePairsWithOverriddenCountry( form_country)); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - expected_profiles); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + expected_profiles); }; // The German profile doesn't expect a state. AutofillProfile kDefaultGermanProfile = @@ -861,8 +863,8 @@ // "en_US" locale. Thus, parsing fails and the phone number is removed. base::HistogramTester histogram_tester; expected_profile.ClearFields({PHONE_HOME_WHOLE_NUMBER}); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - {expected_profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + {expected_profile}); EXPECT_THAT(histogram_tester.GetAllSamples(kHistogramName), testing::UnorderedElementsAre(base::Bucket(false, 1))); } @@ -879,8 +881,8 @@ // profile's country is "DE". EXPECT_TRUE(expected_profile.SetInfo( PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16(kNationalNumber), kLocale)); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - {expected_profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + {expected_profile}); EXPECT_THAT(histogram_tester.GetAllSamples(kHistogramName), testing::UnorderedElementsAre(base::Bucket(true, 1))); } @@ -907,7 +909,7 @@ base::test::ScopedFeatureList ignore_invalid_country_feature; ignore_invalid_country_feature.InitAndEnableFeature( features::kAutofillIgnoreInvalidCountryOnImport); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } } @@ -920,8 +922,8 @@ auto profile_without_number = ConstructDefaultProfile(); profile_without_number.ClearFields({PHONE_HOME_WHOLE_NUMBER}); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - {profile_without_number}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + {profile_without_number}); } // ImportAddressProfiles tests. @@ -947,7 +949,7 @@ form.fields.push_back(field); FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); const std::vector<AutofillProfile*>& results = personal_data_manager_->GetProfiles(); @@ -993,7 +995,7 @@ form.fields.push_back(field); FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); const std::vector<AutofillProfile*>& results = personal_data_manager_->GetProfiles(); @@ -1047,7 +1049,7 @@ form.fields.push_back(field); FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); const std::vector<AutofillProfile*>& results = personal_data_manager_->GetProfiles(); @@ -1093,7 +1095,7 @@ form.fields.push_back(field); FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); const std::vector<AutofillProfile*>& results = personal_data_manager_->GetProfiles(); @@ -1136,7 +1138,7 @@ form.fields.push_back(field); FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); const std::vector<AutofillProfile*>& results = personal_data_manager_->GetProfiles(); @@ -1154,21 +1156,21 @@ TEST_P(FormDataImporterTest, ImportAddressProfiles) { std::unique_ptr<FormStructure> form_structure = ConstructDefaultProfileFormStructure(); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } TEST_P(FormDataImporterTest, ImportSecondAddressProfiles) { std::unique_ptr<FormStructure> form_structure = ConstructSecondProfileFormStructure(); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - {ConstructSecondProfile()}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + {ConstructSecondProfile()}); } TEST_P(FormDataImporterTest, ImportThirdAddressProfiles) { std::unique_ptr<FormStructure> form_structure = ConstructThirdProfileFormStructure(); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - {ConstructThirdProfile()}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + {ConstructThirdProfile()}); } // Test that with dependent locality parsing enabled, dependent locality fields @@ -1185,7 +1187,7 @@ "Bosques de las Lomas"); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(mx_profile); - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *form_structure, {ConstructProfileFromTypeValuePairs(mx_profile)}); } @@ -1194,10 +1196,10 @@ TEST_P(FormDataImporterTest, ImportAddressProfiles_DontAllowPrompt) { std::unique_ptr<FormStructure> form_structure = ConstructDefaultProfileFormStructure(); - ImportAddressProfiles(/*extraction_successful=*/true, *form_structure, - /*skip_waiting_on_pdm=*/true, - /*allow_save_prompts=*/false); - VerifyExpectationForImportedAddressProfiles({}); + ExtractAddressProfiles(/*extraction_successful=*/true, *form_structure, + /*skip_waiting_on_pdm=*/true, + /*allow_save_prompts=*/false); + VerifyExpectationForExtractedAddressProfiles({}); } TEST_P(FormDataImporterTest, ImportAddressProfileFromUnifiedSection) { @@ -1208,7 +1210,7 @@ form_structure->field(4)->section = Section::FromAutocomplete({.section = "another_section"}); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } TEST_P(FormDataImporterTest, ImportAddressProfiles_BadEmail) { @@ -1238,7 +1240,7 @@ {ADDRESS_HOME_STATE, kDefaultState}, {ADDRESS_HOME_ZIP, kDefaultZip}}); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } // Tests two email fields containing different values blocks profile import. @@ -1259,8 +1261,8 @@ ImportAddressProfileAndVerifyImportOfNoProfile(*form_structure); } -// Tests that multiple phone numbers do not block profile import and the first -// one is saved. +// Tests that multiple phone numbers do not block profile extraction and the +// first one is saved. TEST_P(FormDataImporterTest, ImportAddressProfiles_MultiplePhoneNumbers) { base::test::ScopedFeatureList enable_import_when_multiple_phones_feature; enable_import_when_multiple_phones_feature.InitAndEnableFeature( @@ -1279,7 +1281,7 @@ {ADDRESS_HOME_STATE, kDefaultState}, {ADDRESS_HOME_ZIP, kDefaultZip}}); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } // Tests that multiple phone numbers do not block profile import and the first @@ -1319,7 +1321,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromFormData(form_data); - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *form_structure, {ConstructProfileFromTypeValuePairs( {{NAME_FIRST, kDefaultFirstName}, @@ -1362,7 +1364,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {profile}); } TEST_P(FormDataImporterTest, ImportAddressProfiles_MinimumAddressGB) { @@ -1379,7 +1381,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {profile}); } TEST_P(FormDataImporterTest, ImportAddressProfiles_MinimumAddressGI) { @@ -1394,7 +1396,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {profile}); } TEST_P(FormDataImporterTest, @@ -1421,7 +1423,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromFormData(form_data); - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *form_structure, {ConstructProfileFromTypeValuePairs( {{NAME_FIRST, kDefaultFirstName}, @@ -1435,13 +1437,13 @@ {ADDRESS_HOME_COUNTRY, kDefaultCountry}})}); } -// Test that even from unfocusable fields we import. +// Test that even from unfocusable fields we extract. TEST_P(FormDataImporterTest, ImportAddressProfiles_UnFocussableFields) { std::unique_ptr<FormStructure> form_structure = ConstructDefaultProfileFormStructure(); // Set the Address line field as unfocusable. form_structure->field(4)->is_focusable = false; - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } TEST_P(FormDataImporterTest, ImportAddressProfiles_MultilineAddress) { @@ -1460,7 +1462,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {profile}); } TEST_P(FormDataImporterTest, @@ -1469,8 +1471,8 @@ ConstructDefaultProfileFormStructure(); AutofillProfile default_profile = ConstructDefaultProfile(); - ImportAddressProfilesAndVerifyExpectation(*default_form_structure, - {default_profile}); + ExtractAddressProfilesAndVerifyExpectation(*default_form_structure, + {default_profile}); // Now import a second profile from a different form submission. std::unique_ptr<FormStructure> alternative_form_structure = @@ -1478,14 +1480,14 @@ AutofillProfile alternative_profile = ConstructSecondProfile(); // Verify that both profiles have been imported. - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *alternative_form_structure, {alternative_profile, default_profile}); } TEST_P(FormDataImporterTest, ImportAddressProfiles_TwoValidProfilesSameForm) { std::unique_ptr<FormStructure> form_structure = ConstructShippingAndBillingFormStructure(); - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *form_structure, {ConstructDefaultProfile(), ConstructSecondProfile()}); } @@ -1507,7 +1509,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromFormData(form_data); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } // A maximum of two address profiles are imported per form. @@ -1535,9 +1537,9 @@ std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(profile_type_value_pairs); - // Import from the form structure and verify that only the first two profiles - // are imported. - ImportAddressProfilesAndVerifyExpectation( + // Extract from the form structure and verify that only the first two profiles + // are extracted. + ExtractAddressProfilesAndVerifyExpectation( *form_structure, {ConstructDefaultProfile(), ConstructSecondProfile()}); } @@ -1556,8 +1558,8 @@ std::unique_ptr<FormStructure> initial_form_structure = ConstructFormStructureFromTypeValuePairs(initial_type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*initial_form_structure, - {initial_profile}); + ExtractAddressProfilesAndVerifyExpectation(*initial_form_structure, + {initial_profile}); // Create a second form structure with an additional country and a differently // formatted phone number @@ -1591,9 +1593,9 @@ // Country information is added. {ADDRESS_HOME_COUNTRY, "US"}}; - // Verify that importing the conflicting profile will result in an update of + // Verify that extracting the conflicting profile will result in an update of // the existing profile rather than creating a new one. - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *conflicting_form_structure, {ConstructProfileFromTypeValuePairs(resulting_type_value_pairs)}); } @@ -1613,8 +1615,8 @@ std::unique_ptr<FormStructure> initial_form_structure = ConstructFormStructureFromTypeValuePairs(initial_type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*initial_form_structure, - {initial_profile}); + ExtractAddressProfilesAndVerifyExpectation(*initial_form_structure, + {initial_profile}); // Create a superset that includes a new email address. TypeValuePairs superset_type_value_pairs = initial_type_value_pairs; @@ -1629,10 +1631,10 @@ std::unique_ptr<FormStructure> superset_form_structure = ConstructFormStructureFromTypeValuePairs(superset_type_value_pairs); - // Verify that importing the superset profile will result in an update of + // Verify that extracting the superset profile will result in an update of // the existing profile rather than creating a new one. - ImportAddressProfilesAndVerifyExpectation(*superset_form_structure, - {superset_profile}); + ExtractAddressProfilesAndVerifyExpectation(*superset_form_structure, + {superset_profile}); } TEST_P(FormDataImporterTest, ImportAddressProfiles_MissingInfoInNew) { @@ -1661,15 +1663,15 @@ // First import the superset profile. std::unique_ptr<FormStructure> superset_form_structure = ConstructFormStructureFromTypeValuePairs(superset_type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*superset_form_structure, - {superset_profile}); + ExtractAddressProfilesAndVerifyExpectation(*superset_form_structure, + {superset_profile}); - // Than import the subset profile and verify that the stored profile is still + // Than extract the subset profile and verify that the stored profile is still // the superset. std::unique_ptr<FormStructure> subset_form_structure = ConstructFormStructureFromTypeValuePairs(subset_type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*superset_form_structure, - {superset_profile}); + ExtractAddressProfilesAndVerifyExpectation(*superset_form_structure, + {superset_profile}); } TEST_P(FormDataImporterTest, ImportAddressProfiles_InsufficientAddress) { @@ -1734,7 +1736,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); // Expect that no new profile is saved. const std::vector<AutofillProfile*>& results = @@ -1752,7 +1754,7 @@ FormStructure form_structure2(form); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure2); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure2); // Expect that no new profile is saved. const std::vector<AutofillProfile*>& results2 = @@ -1809,7 +1811,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); // The form submission should result in a change of name structure. profile.SetRawInfoWithVerificationStatus(NAME_FIRST, u"Marion Mitchell", @@ -1834,7 +1836,7 @@ FormStructure form_structure2(form); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure2); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure2); // Expect that no new profile is saved. const std::vector<AutofillProfile*>& results2 = @@ -1898,7 +1900,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); // The form submission should result in a change of the address structure. profile.SetRawInfoWithVerificationStatus( @@ -1946,7 +1948,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/false, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/false, form_structure); // Since no refresh is expected, reload the data from the database to make // sure no changes were written out. @@ -1993,7 +1995,7 @@ // the page language is not set. FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/false, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/false, form_structure); ASSERT_EQ(0U, personal_data_manager_->GetProfiles().size()); ASSERT_EQ(0U, personal_data_manager_->GetCreditCards().size()); @@ -2001,7 +2003,7 @@ // Set the page language to match the localized country value and try again. autofill_client_->GetLanguageState()->SetSourceLanguage("de"); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); // There should be one imported address profile. ASSERT_EQ(1U, personal_data_manager_->GetProfiles().size()); @@ -2046,7 +2048,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/true, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/true, form_structure); AutofillProfile expected(base::GenerateGUID(), test::kEmptyOrigin); test::SetProfileInfo(&expected, "George", nullptr, "Washington", @@ -2092,7 +2094,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/false, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/false, form_structure); // Since no refresh is expected, reload the data from the database to make // sure no changes were written out. @@ -2102,15 +2104,15 @@ ASSERT_EQ(0U, personal_data_manager_->GetCreditCards().size()); } -// ImportCreditCard tests. +// ExtractCreditCard tests. // Tests that a valid credit card is extracted. -TEST_P(FormDataImporterTest, ImportCreditCard_Valid) { +TEST_P(FormDataImporterTest, ExtractCreditCard_Valid) { std::unique_ptr<FormStructure> form_structure = ConstructDefaultCreditCardFormStructure(); base::HistogramTester histogram_tester; absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(*form_structure); + ExtractCreditCard(*form_structure); EXPECT_TRUE(credit_card_import_candidate); histogram_tester.ExpectUniqueSample( "Autofill.SubmittedCardState", @@ -2128,7 +2130,7 @@ } // Tests that an invalid credit card number is not extracted. -TEST_P(FormDataImporterTest, ImportCreditCard_InvalidCardNumber) { +TEST_P(FormDataImporterTest, ExtractCreditCard_InvalidCardNumber) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2139,7 +2141,7 @@ form_structure.DetermineHeuristicTypes(nullptr, nullptr); base::HistogramTester histogram_tester; absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_FALSE(credit_card_import_candidate); histogram_tester.ExpectUniqueSample("Autofill.SubmittedCardState", AutofillMetrics::HAS_EXPIRATION_DATE_ONLY, @@ -2155,7 +2157,7 @@ // Tests that a credit card with an empty expiration can be extracted due to the // expiration date fix flow. TEST_P(FormDataImporterTest, - ImportCreditCard_InvalidExpiryDate_EditableExpirationExpOn) { + ExtractCreditCard_InvalidExpiryDate_EditableExpirationExpOn) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2165,7 +2167,7 @@ form_structure.DetermineHeuristicTypes(nullptr, nullptr); base::HistogramTester histogram_tester; absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); histogram_tester.ExpectUniqueSample("Autofill.SubmittedCardState", AutofillMetrics::HAS_CARD_NUMBER_ONLY, 1); @@ -2174,7 +2176,7 @@ // Tests that an expired credit card can be extracted due to the expiration date // fix flow. TEST_P(FormDataImporterTest, - ImportCreditCard_ExpiredExpiryDate_EditableExpirationExpOn) { + ExtractCreditCard_ExpiredExpiryDate_EditableExpirationExpOn) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2185,7 +2187,7 @@ form_structure.DetermineHeuristicTypes(nullptr, nullptr); base::HistogramTester histogram_tester; absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); histogram_tester.ExpectUniqueSample("Autofill.SubmittedCardState", AutofillMetrics::HAS_CARD_NUMBER_ONLY, 1); @@ -2193,7 +2195,7 @@ // Tests that a valid credit card is extracted when the option text for month // select can't be parsed but its value can. -TEST_P(FormDataImporterTest, ImportCreditCard_MonthSelectInvalidText) { +TEST_P(FormDataImporterTest, ExtractCreditCard_MonthSelectInvalidText) { // Add a single valid credit card form with an invalid option value. FormData form; form.url = GURL("https://www.foo.com"); @@ -2212,7 +2214,7 @@ form_structure.DetermineHeuristicTypes(nullptr, nullptr); base::HistogramTester histogram_tester; absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); histogram_tester.ExpectUniqueSample( "Autofill.SubmittedCardState", @@ -2230,12 +2232,12 @@ UnorderedElementsCompareEqual(expected)); } -TEST_P(FormDataImporterTest, ImportCreditCard_TwoValidCards) { +TEST_P(FormDataImporterTest, ExtractCreditCard_TwoValidCards) { // Start with a single valid credit card form. std::unique_ptr<FormStructure> form_structure1 = ConstructDefaultCreditCardFormStructure(); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(*form_structure1); + ExtractCreditCard(*form_structure1); EXPECT_TRUE(credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate); @@ -2258,7 +2260,7 @@ form_structure2.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate2 = - ImportCreditCard(form_structure2); + ExtractCreditCard(form_structure2); EXPECT_TRUE(credit_card_import_candidate2); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate2); @@ -2276,7 +2278,7 @@ } // This form has the expiration year as one field with MM/YY. -TEST_P(FormDataImporterTest, ImportCreditCard_Month2DigitYearCombination) { +TEST_P(FormDataImporterTest, ExtractCreditCard_Month2DigitYearCombination) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2296,7 +2298,7 @@ } // This form has the expiration year as one field with MM/YYYY. -TEST_P(FormDataImporterTest, ImportCreditCard_Month4DigitYearCombination) { +TEST_P(FormDataImporterTest, ExtractCreditCard_Month4DigitYearCombination) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2316,7 +2318,7 @@ } // This form has the expiration year as one field with M/YYYY. -TEST_P(FormDataImporterTest, ImportCreditCard_1DigitMonth4DigitYear) { +TEST_P(FormDataImporterTest, ExtractCreditCard_1DigitMonth4DigitYear) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2336,7 +2338,7 @@ } // This form has the expiration year as a 2-digit field. -TEST_P(FormDataImporterTest, ImportCreditCard_2DigitYear) { +TEST_P(FormDataImporterTest, ExtractCreditCard_2DigitYear) { FormData form; form.url = GURL("https://www.foo.com"); @@ -2360,7 +2362,7 @@ // Tests that a credit card is extracted when the card matches a masked server // card. TEST_P(FormDataImporterTest, - ImportCreditCard_DuplicateServerCards_ExtractMaskedCard) { + ExtractCreditCard_DuplicateServerCards_ExtractMaskedCard) { // Add a masked server card. std::vector<CreditCard> server_cards; server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123")); @@ -2386,7 +2388,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); ASSERT_TRUE(credit_card_import_candidate.value().record_type() == CreditCard::MASKED_SERVER_CARD); @@ -2395,7 +2397,7 @@ // Tests that a credit card is extracted when it matches a full server // card. TEST_P(FormDataImporterTest, - ImportCreditCard_DuplicateServerCards_ExtractFullCard) { + ExtractCreditCard_DuplicateServerCards_ExtractFullCard) { // Add a full server card. std::vector<CreditCard> server_cards; server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789")); @@ -2420,13 +2422,13 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); EXPECT_EQ(credit_card_import_candidate.value().record_type(), CreditCard::RecordType::FULL_SERVER_CARD); } -TEST_P(FormDataImporterTest, ImportCreditCard_SameCreditCardWithConflict) { +TEST_P(FormDataImporterTest, ExtractCreditCard_SameCreditCardWithConflict) { // Start with a single valid credit card form. FormData form1; form1.url = GURL("https://wwww.foo.com"); @@ -2437,7 +2439,7 @@ FormStructure form_structure1(form1); form_structure1.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure1); + ExtractCreditCard(form_structure1); EXPECT_TRUE(credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate); @@ -2461,7 +2463,7 @@ FormStructure form_structure2(form2); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate2 = - ImportCreditCard(form_structure2); + ExtractCreditCard(form_structure2); EXPECT_TRUE(credit_card_import_candidate2); WaitForOnPersonalDataChanged(); @@ -2477,7 +2479,7 @@ EXPECT_THAT(*results2[0], ComparesEqual(expected2)); } -TEST_P(FormDataImporterTest, ImportCreditCard_ShouldReturnLocalCard) { +TEST_P(FormDataImporterTest, ExtractCreditCard_ShouldReturnLocalCard) { // Start with a single valid credit card form. FormData form1; form1.url = GURL("https://wwww.foo.com"); @@ -2488,7 +2490,7 @@ FormStructure form_structure1(form1); form_structure1.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure1); + ExtractCreditCard(form_structure1); EXPECT_TRUE(credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate); @@ -2512,7 +2514,7 @@ FormStructure form_structure2(form2); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate2 = - ImportCreditCard(form_structure2); + ExtractCreditCard(form_structure2); EXPECT_TRUE(credit_card_import_candidate2); // The local card is returned after an update. EXPECT_TRUE(credit_card_import_candidate2); @@ -2530,7 +2532,7 @@ EXPECT_THAT(*results2[0], ComparesEqual(expected2)); } -TEST_P(FormDataImporterTest, ImportCreditCard_EmptyCardWithConflict) { +TEST_P(FormDataImporterTest, ExtractCreditCard_EmptyCardWithConflict) { // Start with a single valid credit card form. FormData form1; form1.url = GURL("https://wwww.foo.com"); @@ -2542,7 +2544,7 @@ form_structure1.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure1); + ExtractCreditCard(form_structure1); EXPECT_TRUE(credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate); @@ -2565,7 +2567,7 @@ FormStructure form_structure2(form2); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate2 = - ImportCreditCard(form_structure2); + ExtractCreditCard(form_structure2); EXPECT_FALSE(credit_card_import_candidate2); // Since no refresh is expected, reload the data from the database to make @@ -2582,7 +2584,7 @@ EXPECT_THAT(*results2[0], ComparesEqual(expected2)); } -TEST_P(FormDataImporterTest, ImportCreditCard_MissingInfoInNew) { +TEST_P(FormDataImporterTest, ExtractCreditCard_MissingInfoInNew) { // Start with a single valid credit card form. FormData form1; form1.url = GURL("https://wwww.foo.com"); @@ -2593,7 +2595,7 @@ FormStructure form_structure1(form1); form_structure1.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure1); + ExtractCreditCard(form_structure1); EXPECT_TRUE(credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( *credit_card_import_candidate); @@ -2617,7 +2619,7 @@ FormStructure form_structure2(form2); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate2 = - ImportCreditCard(form_structure2); + ExtractCreditCard(form_structure2); EXPECT_TRUE(credit_card_import_candidate2); // Since no refresh is expected, reload the data from the database to make @@ -2644,7 +2646,7 @@ FormStructure form_structure3(form3); form_structure3.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate3 = - ImportCreditCard(form_structure3); + ExtractCreditCard(form_structure3); EXPECT_FALSE(credit_card_import_candidate3); // Since no refresh is expected, reload the data from the database to make @@ -2661,7 +2663,7 @@ EXPECT_THAT(*results3[0], ComparesEqual(expected3)); } -TEST_P(FormDataImporterTest, ImportCreditCard_MissingInfoInOld) { +TEST_P(FormDataImporterTest, ExtractCreditCard_MissingInfoInOld) { // Start with a single valid credit card stored via the preferences. // Note the empty name. CreditCard saved_credit_card(base::GenerateGUID(), test::kEmptyOrigin); @@ -2687,7 +2689,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); WaitForOnPersonalDataChanged(); @@ -2705,7 +2707,7 @@ // We allow the user to store a credit card number with separators via the UI. // We should not try to re-aggregate the same card with the separators stripped. -TEST_P(FormDataImporterTest, ImportCreditCard_SameCardWithSeparators) { +TEST_P(FormDataImporterTest, ExtractCreditCard_SameCardWithSeparators) { // Start with a single valid credit card stored via the preferences. // Note the separators in the credit card number. CreditCard saved_credit_card(base::GenerateGUID(), test::kEmptyOrigin); @@ -2730,7 +2732,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); // Since no refresh is expected, reload the data from the database to make @@ -2747,7 +2749,7 @@ // Ensure that if a verified credit card already exists, aggregated credit cards // cannot modify it in any way. TEST_P(FormDataImporterTest, - ImportCreditCard_ExistingVerifiedCardWithConflict) { + ExtractCreditCard_ExistingVerifiedCardWithConflict) { // Start with a verified credit card. CreditCard credit_card(base::GenerateGUID(), kSettingsOrigin); test::SetCreditCardInfo(&credit_card, "Biggie Smalls", @@ -2772,7 +2774,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); absl::optional<CreditCard> credit_card_import_candidate = - ImportCreditCard(form_structure); + ExtractCreditCard(form_structure); EXPECT_TRUE(credit_card_import_candidate); // Since no refresh is expected, reload the data from the database to make @@ -2786,10 +2788,11 @@ EXPECT_THAT(*results[0], ComparesEqual(credit_card)); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set -// and reset correctly. +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set and +// reset correctly. TEST_P(FormDataImporterTest, - ImportFormData_SecondImportResetsCreditCardRecordType) { + ExtractFormData_SecondImportResetsCreditCardRecordType) { // Start with a single valid credit card stored via the preferences. CreditCard saved_credit_card(base::GenerateGUID(), test::kEmptyOrigin); test::SetCreditCardInfo(&saved_credit_card, "Biggie Smalls", @@ -2812,19 +2815,18 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kLocalCard because upload was - // offered and the card is a local card already on the device. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kLocalCard); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kLocalCard because + // upload was offered and the card is a local card already on the device. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kLocalCard); // Second form is filled with a new card so - // `FormDataImporterTest::imported_credit_card_record_type_` should be reset. - // Simulate a form submission with a new card. + // `FormDataImporterTest::credit_card_import_type_` should be + // reset. Simulate a form submission with a new card. FormData form2; form2.url = GURL("https://wwww.foo.com"); @@ -2833,21 +2835,20 @@ FormStructure form_structure2(form2); form_structure2.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data2 = ImportFormDataAndProcessAddressCandidates( + auto extracted_data2 = ExtractFormDataAndProcessAddressCandidates( form_structure2, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data2.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kNewCard because the imported - // card is not already on the device. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNewCard); + ASSERT_TRUE(extracted_data2.credit_card_import_candidate); + // |credit_card_import_type_| should be kNewCard because the + // imported card is not already on the device. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNewCard); // Third form is an address form and set `payment_methods_autofill_enabled` to - // be false so that the ImportCreditCard won't be called. - // `FormDataImporterTest::imported_credit_card_record_type_` should still be - // reset even if ImportCreditCard is not called. Simulate a form submission - // with no card. + // be false so that the ExtractCreditCard won't be called. + // `FormDataImporterTest::credit_card_import_type_` should + // still be reset even if ExtractCreditCard is not called. Simulate a form + // submission with no card. FormData form3; form3.url = GURL("https://wwww.foo.com"); @@ -2872,21 +2873,21 @@ form3.fields.push_back(field); FormStructure form_structure3(form3); form_structure3.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data3 = ImportFormDataAndProcessAddressCandidates( + auto extracted_data3 = ExtractFormDataAndProcessAddressCandidates( form_structure3, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/false); - // |imported_credit_card_record_type_| should be NO_CARD because no valid card - // was imported from the form. - EXPECT_NE(0u, imported_data3.address_profile_import_candidates.size()); - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNoCard); + // |credit_card_import_type_| should be NO_CARD because no + // valid card was imported from the form. + EXPECT_NE(0u, extracted_data3.address_profile_import_candidates.size()); + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNoCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NewCard) { + ExtractFormData_ExtractCreditCardRecordType_NewCard) { // Simulate a form submission with a new credit card. FormData form; form.url = GURL("https://www.foo.com"); @@ -2896,20 +2897,19 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kNewCard because the imported - // card is not already on the device. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNewCard); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kNewCard because the + // imported card is not already on the device. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNewCard); } -// Ensures that `imported_credit_card_record_type_` is set correctly. +// Ensures that `credit_card_import_type_` is set correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_LocalCard) { + ExtractFormData_ExtractCreditCardRecordType_LocalCard) { // Start with a single valid credit card stored via the preferences. CreditCard saved_credit_card(base::GenerateGUID(), test::kEmptyOrigin); test::SetCreditCardInfo(&saved_credit_card, "Biggie Smalls", @@ -2932,21 +2932,21 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kLocalCard because upload was - // offered and the card is a local card already on the device. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kLocalCard); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kLocalCard because + // upload was offered and the card is a local card already on the device. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kLocalCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_MaskedServerCard) { + ExtractFormData_ExtractCreditCardRecordType_MaskedServerCard) { // Add a masked server card. std::vector<CreditCard> server_cards; server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123")); @@ -2969,20 +2969,20 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be SERVER_CARD. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kServerCard); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be SERVER_CARD. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kServerCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_FullServerCard) { + ExtractFormData_ExtractCreditCardRecordType_FullServerCard) { // Add a full server card. std::vector<CreditCard> server_cards; server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789")); @@ -3005,20 +3005,20 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be SERVER_CARD. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kServerCard); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be SERVER_CARD. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kServerCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NoCard_InvalidCardNumber) { + ExtractFormData_ExtractCreditCardRecordType_NoCard_InvalidCardNumber) { // Simulate a form submission using a credit card with an invalid card number. FormData form; form.url = GURL("https://www.foo.com"); @@ -3028,21 +3028,21 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_FALSE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kNoCard because no valid card - // was successfully imported from the form. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNoCard); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kNoCard because no + // valid card was successfully imported from the form. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNoCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NoCard_VirtualCard) { + ExtractFormData_ExtractCreditCardRecordType_NoCard_VirtualCard) { // Simulate a form submission using a credit card that is known as a virtual // card. FormData form; @@ -3052,22 +3052,22 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); form_data_importer().CacheFetchedVirtualCard(u"1111"); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_FALSE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kNoCard because the card - // imported from the form was a virtual card. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNoCard); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kNoCard because the + // card imported from the form was a virtual card. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNoCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P( FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NewCard_ExpiredCard_WithExpDateFixFlow) { + ExtractFormData_ExtractCreditCardRecordType_NewCard_ExpiredCard_WithExpDateFixFlow) { // Simulate a form submission with an expired credit card. FormData form; form.url = GURL("https://www.foo.com"); @@ -3077,21 +3077,21 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kNewCard because card was - // successfully imported from the form via the expiration date fix flow. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNewCard); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kNewCard because card + // was successfully imported from the form via the expiration date fix flow. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNewCard); } -// Ensures that `FormDataImporterTest::imported_credit_card_record_type_` is set +// Ensures that +// `FormDataImporterTest::credit_card_import_type_` is set // correctly. TEST_P(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NoCard_NoCardOnForm) { + ExtractFormData_ExtractCreditCardRecordType_NoCard_NoCardOnForm) { // Simulate a form submission with no credit card on form. FormData form; form.url = GURL("https://www.foo.com"); @@ -3118,22 +3118,21 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_FALSE(imported_data.credit_card_import_candidate); - // |imported_credit_card_record_type_| should be kNoCard because the form - // doesn't have credit card section. - ASSERT_TRUE( - form_data_importer().imported_credit_card_record_type_for_testing() == - FormDataImporter::ImportedCreditCardRecordType::kNoCard); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); + // |credit_card_import_type_| should be kNoCard because the + // form doesn't have credit card section. + ASSERT_TRUE(form_data_importer().credit_card_import_type_for_testing() == + FormDataImporter::CreditCardImportType::kNoCard); } -// ImportFormData tests (both addresses and credit cards). +// ExtractFormData tests (both addresses and credit cards). // Test that a form with both address and credit card sections imports the // address and the credit card. -TEST_P(FormDataImporterTest, ImportFormData_OneAddressOneCreditCard) { +TEST_P(FormDataImporterTest, ExtractFormData_OneAddressOneCreditCard) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3166,12 +3165,12 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( - *imported_data.credit_card_import_candidate); + *extracted_data.credit_card_import_candidate); WaitForOnPersonalDataChanged(); @@ -3197,7 +3196,7 @@ // Test that a form with two address sections and a credit card section does not // import the address but does import the credit card. -TEST_P(FormDataImporterTest, ImportFormData_TwoAddressesOneCreditCard) { +TEST_P(FormDataImporterTest, ExtractFormData_TwoAddressesOneCreditCard) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3250,14 +3249,14 @@ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()) .Times(testing::AnyNumber()); // Still returns true because the credit card import was successful. - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); run_loop.Run(); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( - *imported_data.credit_card_import_candidate); + *extracted_data.credit_card_import_candidate); WaitForOnPersonalDataChanged(); @@ -3275,21 +3274,21 @@ } #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -TEST_P(FormDataImporterTest, ImportFormData_ImportIbanRecordType_NoIban) { +TEST_P(FormDataImporterTest, ExtractFormData_ImportIbanRecordType_NoIban) { // Simulate a form submission with no IBAN. FormData form; form.url = GURL("https://www.foo.com"); FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_FALSE(imported_data.iban_import_candidate); + ASSERT_FALSE(extracted_data.iban_import_candidate); } TEST_P(FormDataImporterTest, - ImportFormData_ImportIbanRecordType_IbanAutofill_NewIban) { + ExtractFormData_ImportIbanRecordType_IbanAutofill_NewIban) { // Simulate a form submission with a new IBAN. FormData form; form.url = GURL("https://www.foo.com"); @@ -3298,19 +3297,19 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); if (base::FeatureList::IsEnabled(features::kAutofillFillIbanFields)) { - ASSERT_TRUE(imported_data.iban_import_candidate); - ASSERT_TRUE(imported_data.iban_import_candidate->record_type() == + ASSERT_TRUE(extracted_data.iban_import_candidate); + ASSERT_TRUE(extracted_data.iban_import_candidate->record_type() == IBAN::NEW_IBAN); } else { - ASSERT_FALSE(imported_data.iban_import_candidate); + ASSERT_FALSE(extracted_data.iban_import_candidate); } } -TEST_P(FormDataImporterTest, ImportFormData_ImportIbanRecordType_LocalIban) { +TEST_P(FormDataImporterTest, ExtractFormData_ImportIbanRecordType_LocalIban) { IBAN iban; iban.set_value(u"IE12 BOFI 9000 0112 3456 78"); personal_data_manager_->AddIBAN(iban); @@ -3329,15 +3328,15 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); if (base::FeatureList::IsEnabled(features::kAutofillFillIbanFields)) { - ASSERT_TRUE(imported_data.iban_import_candidate); - ASSERT_TRUE(imported_data.iban_import_candidate->record_type() == + ASSERT_TRUE(extracted_data.iban_import_candidate); + ASSERT_TRUE(extracted_data.iban_import_candidate->record_type() == IBAN::LOCAL_IBAN); } else { - ASSERT_FALSE(imported_data.iban_import_candidate); + ASSERT_FALSE(extracted_data.iban_import_candidate); } } @@ -3345,7 +3344,7 @@ // Test that a form with both address and credit card sections imports only the // the credit card if addresses are disabled. -TEST_P(FormDataImporterTest, ImportFormData_AddressesDisabledOneCreditCard) { +TEST_P(FormDataImporterTest, ExtractFormData_AddressesDisabledOneCreditCard) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3376,12 +3375,12 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/false, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( - *imported_data.credit_card_import_candidate); + *extracted_data.credit_card_import_candidate); WaitForOnPersonalDataChanged(); @@ -3400,7 +3399,7 @@ // Test that a form with both address and credit card sections imports only the // the address if credit cards are disabled. -TEST_P(FormDataImporterTest, ImportFormData_OneAddressCreditCardDisabled) { +TEST_P(FormDataImporterTest, ExtractFormData_OneAddressCreditCardDisabled) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3433,10 +3432,10 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/false); - ASSERT_FALSE(imported_data.credit_card_import_candidate); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); WaitForOnPersonalDataChanged(); @@ -3458,7 +3457,7 @@ // Test that a form with both address and credit card sections imports nothing // if both addressed and credit cards are disabled. -TEST_P(FormDataImporterTest, ImportFormData_AddressCreditCardDisabled) { +TEST_P(FormDataImporterTest, ExtractFormData_AddressCreditCardDisabled) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3489,10 +3488,10 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/false, /*payment_methods_autofill_enabled=*/false); - ASSERT_FALSE(imported_data.credit_card_import_candidate); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); // Test that addresses were not saved. EXPECT_EQ(0U, personal_data_manager_->GetProfiles().size()); @@ -3541,15 +3540,15 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); } // Tests that a credit card form that is hidden after receiving input still // imports the card. -TEST_P(FormDataImporterTest, ImportFormData_HiddenCreditCardFormAfterEntered) { +TEST_P(FormDataImporterTest, ExtractFormData_HiddenCreditCardFormAfterEntered) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3576,12 +3575,12 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); personal_data_manager_->OnAcceptedLocalCreditCardSave( - *imported_data.credit_card_import_candidate); + *extracted_data.credit_card_import_candidate); WaitForOnPersonalDataChanged(); @@ -3598,14 +3597,14 @@ // Ensures that no UPI ID value is returned when there's a credit card and no // UPI ID. TEST_P(FormDataImporterTest, - ImportFormData_DontSetUpiIdWhenOnlyCreditCardExists) { + ExtractFormData_DontSetUpiIdWhenOnlyCreditCardExists) { std::unique_ptr<FormStructure> form_structure = ConstructDefaultCreditCardFormStructure(); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( *form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); - ASSERT_FALSE(imported_data.imported_upi_id.has_value()); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); + ASSERT_FALSE(extracted_data.extracted_upi_id.has_value()); } TEST_P(FormDataImporterTest, @@ -3662,13 +3661,13 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); // Ensure that we imported the server version of the card, not the local // version. - ASSERT_TRUE(imported_data.credit_card_import_candidate->record_type() == + ASSERT_TRUE(extracted_data.credit_card_import_candidate->record_type() == CreditCard::FULL_SERVER_CARD); // Check that both of the local cards we have added were updated. @@ -3716,10 +3715,10 @@ base::HistogramTester histogram_tester; FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); histogram_tester.ExpectUniqueSample( "Autofill.SubmittedServerCardExpirationStatus", AutofillMetrics::FULL_SERVER_CARD_EXPIRATION_DATE_MATCHED, 1); @@ -3760,10 +3759,10 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_FALSE(imported_data.credit_card_import_candidate); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); } // Ensure that we don't offer to save if we already have same card stored as a @@ -3801,10 +3800,10 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_FALSE(imported_data.credit_card_import_candidate); + ASSERT_FALSE(extracted_data.credit_card_import_candidate); } // Ensure that we still offer to save if we have different cards stored as a @@ -3843,10 +3842,10 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); } TEST_P(FormDataImporterTest, @@ -3884,10 +3883,10 @@ base::HistogramTester histogram_tester; FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); histogram_tester.ExpectUniqueSample( "Autofill.SubmittedServerCardExpirationStatus", AutofillMetrics::FULL_SERVER_CARD_EXPIRATION_DATE_DID_NOT_MATCH, 1); @@ -3928,10 +3927,10 @@ base::HistogramTester histogram_tester; FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); histogram_tester.ExpectUniqueSample( "Autofill.SubmittedServerCardExpirationStatus", AutofillMetrics::MASKED_SERVER_CARD_EXPIRATION_DATE_MATCHED, 1); @@ -3973,16 +3972,16 @@ base::HistogramTester histogram_tester; FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.credit_card_import_candidate); + ASSERT_TRUE(extracted_data.credit_card_import_candidate); histogram_tester.ExpectUniqueSample( "Autofill.SubmittedServerCardExpirationStatus", AutofillMetrics::MASKED_SERVER_CARD_EXPIRATION_DATE_DID_NOT_MATCH, 1); } -TEST_P(FormDataImporterTest, ImportUpiId) { +TEST_P(FormDataImporterTest, ExtractUpiId) { FormData form; form.url = GURL("https://www.foo.com"); @@ -3994,14 +3993,14 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/false, /*payment_methods_autofill_enabled=*/true); - ASSERT_TRUE(imported_data.imported_upi_id.has_value()); - EXPECT_EQ(imported_data.imported_upi_id.value(), "user@indianbank"); + ASSERT_TRUE(extracted_data.extracted_upi_id.has_value()); + EXPECT_EQ(extracted_data.extracted_upi_id.value(), "user@indianbank"); } -TEST_P(FormDataImporterTest, ImportUpiIdDisabled) { +TEST_P(FormDataImporterTest, ExtractUpiIdDisabled) { FormData form; form.url = GURL("https://www.foo.com"); @@ -4013,13 +4012,13 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/false, /*payment_methods_autofill_enabled=*/false); - ASSERT_FALSE(imported_data.imported_upi_id.has_value()); + ASSERT_FALSE(extracted_data.extracted_upi_id.has_value()); } -TEST_P(FormDataImporterTest, ImportUpiIdIgnoreNonUpiId) { +TEST_P(FormDataImporterTest, ExtractUpiIdIgnoreNonUpiId) { FormData form; form.url = GURL("https://www.foo.com"); @@ -4031,10 +4030,10 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - auto imported_data = ImportFormDataAndProcessAddressCandidates( + auto extracted_data = ExtractFormDataAndProcessAddressCandidates( form_structure, /*profile_autofill_enabled=*/false, /*payment_methods_autofill_enabled=*/false); - ASSERT_FALSE(imported_data.imported_upi_id.has_value()); + ASSERT_FALSE(extracted_data.extracted_upi_id.has_value()); } TEST_P(FormDataImporterTest, SilentlyUpdateExistingProfileByIncompleteProfile) { @@ -4078,7 +4077,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/false, form_structure); + ExtractAddressProfiles(/*extraction_successful=*/false, form_structure); // Expect that no new profile is saved. const std::vector<AutofillProfile*>& results = @@ -4134,9 +4133,9 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/false, form_structure, - /*skip_waiting_on_pdm=*/false, - /*allow_save_prompts=*/false); + ExtractAddressProfiles(/*extraction_successful=*/false, form_structure, + /*skip_waiting_on_pdm=*/false, + /*allow_save_prompts=*/false); // Expect that no new profile is saved and the existing profile is updated. const std::vector<AutofillProfile*>& results = @@ -4190,8 +4189,8 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ImportAddressProfiles(/*extraction_successful=*/false, form_structure, - /*skip_waiting_on_pdm=*/true); + ExtractAddressProfiles(/*extraction_successful=*/false, form_structure, + /*skip_waiting_on_pdm=*/true); // Expect that no new profile is saved. const std::vector<AutofillProfile*>& results = @@ -4221,7 +4220,7 @@ ConstructFormStructureFromTypeValuePairs(type_value_pairs); type_value_pairs.pop_back(); // Remove state manually for verification. base::HistogramTester histogram_tester; - ImportAddressProfilesAndVerifyExpectation( + ExtractAddressProfilesAndVerifyExpectation( *form_structure, {ConstructProfileFromTypeValuePairs(type_value_pairs)}); // State was removed. Expect the metrics to behave accordingly. @@ -4233,7 +4232,7 @@ AutofillMetrics::SettingsVisibleFieldTypeForMetrics::kState, 1); } -// Tests a 2-page multi-step import. +// Tests a 2-page multi-step extraction. TEST_P(FormDataImporterTest, MultiStepImport) { base::test::ScopedFeatureList multistep_import_feature; multistep_import_feature.InitAndEnableFeature( @@ -4241,10 +4240,10 @@ std::unique_ptr<FormStructure> form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/1); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/2); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } // Tests that a complemented country is discarded in favour of an observed one. @@ -4262,7 +4261,7 @@ std::pair<ServerFieldType, std::string>(ADDRESS_HOME_COUNTRY, "US"))); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); // Now import a profile without a country. The country is thus be complemented // to the variation country "DE". @@ -4272,7 +4271,7 @@ [](auto& pair) { return pair.first; })); form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } // Tests that when multi-step complements are enabled, complete profiles those @@ -4284,23 +4283,23 @@ features::kAutofillEnableMultiStepImports, {{features::kAutofillEnableMultiStepImportComplements.name, "true"}}); - // Import the default profile without an email address. + // Extract the default profile without an email address. TypeValuePairs type_value_pairs = GetDefaultProfileTypeValuePairs(); SetValueForType(type_value_pairs, EMAIL_ADDRESS, ""); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - // Using `ImportAddressProfileAndVerifyImportOfDefaultProfile()` doesn't + // Using `ExtractAddressProfileAndVerifyExtractionOfDefaultProfile()` doesn't // suffice, as the multi-step complement candidate is only added in the // "ProcessAddressCandidates" step. - ImportFormDataAndProcessAddressCandidates(*form_structure); - VerifyExpectationForImportedAddressProfiles( + ExtractFormDataAndProcessAddressCandidates(*form_structure); + VerifyExpectationForExtractedAddressProfiles( {ConstructProfileFromTypeValuePairs(type_value_pairs)}); // Import the email address in a separate form. Without multi-step updates, // this information cannot be associated to a profile. The resulting profile // is the default one. form_structure = ConstructDefaultEmailFormStructure(); - ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure); + ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } // Tests that when an imported profile is modified through external means (e.g. @@ -4312,13 +4311,13 @@ features::kAutofillEnableMultiStepImports, {{features::kAutofillEnableMultiStepImportComplements.name, "true"}}); - // Import the default profile without an email address. + // Extract the default profile without an email address. TypeValuePairs type_value_pairs = GetDefaultProfileTypeValuePairs(); SetValueForType(type_value_pairs, EMAIL_ADDRESS, ""); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportFormDataAndProcessAddressCandidates(*form_structure); - VerifyExpectationForImportedAddressProfiles( + ExtractFormDataAndProcessAddressCandidates(*form_structure); + VerifyExpectationForExtractedAddressProfiles( {ConstructProfileFromTypeValuePairs(type_value_pairs)}); // Update the profile's ZIP through external means. @@ -4333,8 +4332,8 @@ AutofillProfile expected_profile = ConstructDefaultProfile(); expected_profile.SetInfoWithVerificationStatus( ADDRESS_HOME_ZIP, u"12345", kLocale, VerificationStatus::kObserved); - ImportAddressProfilesAndVerifyExpectation(*form_structure, - {expected_profile}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, + {expected_profile}); } // Tests that when an imported profile is deleted through external means (e.g. @@ -4346,13 +4345,13 @@ features::kAutofillEnableMultiStepImports, {{features::kAutofillEnableMultiStepImportComplements.name, "true"}}); - // Import the default profile without an email address. + // Extract the default profile without an email address. TypeValuePairs type_value_pairs = GetDefaultProfileTypeValuePairs(); SetValueForType(type_value_pairs, EMAIL_ADDRESS, ""); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromTypeValuePairs(type_value_pairs); - ImportFormDataAndProcessAddressCandidates(*form_structure); - VerifyExpectationForImportedAddressProfiles( + ExtractFormDataAndProcessAddressCandidates(*form_structure); + VerifyExpectationForExtractedAddressProfiles( {ConstructProfileFromTypeValuePairs(type_value_pairs)}); // Remove the profile through external means. @@ -4376,7 +4375,7 @@ form.url = GURL("https://www.foo.com"); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromFormData(form); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); form = ConstructSplitDefaultFormData(/*part=*/2); form.url = GURL("https://wwww.bar.com"); @@ -4394,7 +4393,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/1); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); test_clock.Advance(base::Minutes(31)); @@ -4411,7 +4410,7 @@ std::unique_ptr<FormStructure> form_structure = ConstructSplitDefaultProfileFormStructure(/*part=*/1); - ImportAddressProfilesAndVerifyExpectation(*form_structure, {}); + ExtractAddressProfilesAndVerifyExpectation(*form_structure, {}); personal_data_manager_->OnURLsDeleted( /*history_service=*/nullptr, @@ -4434,10 +4433,10 @@ std::unique_ptr<FormStructure> form_structure = ConstructShippingAndBillingFormStructure(); FormSignature form_signature = form_structure->form_signature(); - // Don't use `ImportAddressProfileAndVerifyImportOfDefaultProfile()`, as this - // function assumes we know it's an address form already. Form associations - // are tracked in `ImportFormData()` instead. - ImportFormDataAndProcessAddressCandidates(*form_structure); + // Don't use `ExtractAddressProfileAndVerifyExtractionOfDefaultProfile()`, as + // this function assumes we know it's an address form already. Form + // associations are tracked in `ExtractFormData()` instead. + ExtractFormDataAndProcessAddressCandidates(*form_structure); absl::optional<FormStructure::FormAssociations> associations = form_data_importer().GetFormAssociations(form_signature); @@ -4460,7 +4459,8 @@ form_data_importer().ProcessIBANImportCandidate(iban_import_candidate)); } -TEST_P(FormDataImporterTest, ImportFormData_ProcessIBANImportCandidate_NoIban) { +TEST_P(FormDataImporterTest, + ExtractFormData_ProcessIBANImportCandidate_NoIban) { // Simulate a form submission with a new IBAN. FormData form; form.url = GURL("https://www.foo.com"); @@ -4470,14 +4470,14 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ASSERT_FALSE(ImportFormDataAndProcessIBANCandidates( + ASSERT_FALSE(ExtractFormDataAndProcessIBANCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true)); } TEST_P( FormDataImporterTest, - ImportFormData_ProcessIBANImportCandidate_PaymentMethodsSettingDisabled) { + ExtractFormData_ProcessIBANImportCandidate_PaymentMethodsSettingDisabled) { // Simulate a form submission with a new IBAN. FormData form; form.url = GURL("https://www.foo.com"); @@ -4487,13 +4487,13 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ASSERT_FALSE(ImportFormDataAndProcessIBANCandidates( + ASSERT_FALSE(ExtractFormDataAndProcessIBANCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/false)); } TEST_P(FormDataImporterTest, - ImportFormData_ProcessIBANImportCandidate_NewIban) { + ExtractFormData_ProcessIBANImportCandidate_NewIban) { // Simulate a form submission with a new IBAN. FormData form; form.url = GURL("https://www.foo.com"); @@ -4504,13 +4504,13 @@ form_structure.DetermineHeuristicTypes(nullptr, nullptr); ASSERT_EQ(base::FeatureList::IsEnabled(features::kAutofillFillIbanFields), - ImportFormDataAndProcessIBANCandidates( + ExtractFormDataAndProcessIBANCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true)); } TEST_P(FormDataImporterTest, - ImportFormData_ProcessIBANImportCandidate_LocalIban) { + ExtractFormData_ProcessIBANImportCandidate_LocalIban) { IBAN iban; iban.set_value(base::UTF8ToUTF16(std::string(kIbanValue))); personal_data_manager_->AddIBAN(iban); @@ -4525,13 +4525,13 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ASSERT_FALSE(ImportFormDataAndProcessIBANCandidates( + ASSERT_FALSE(ExtractFormDataAndProcessIBANCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true)); } TEST_P(FormDataImporterTest, - ImportFormData_ProcessIBANImportCandidate_MaxStrikes) { + ExtractFormData_ProcessIBANImportCandidate_MaxStrikes) { IBANSaveStrikeDatabase iban_save_strike_database = IBANSaveStrikeDatabase(autofill_client_->GetStrikeDatabase()); @@ -4547,7 +4547,7 @@ FormStructure form_structure(form); form_structure.DetermineHeuristicTypes(nullptr, nullptr); - ASSERT_FALSE(ImportFormDataAndProcessIBANCandidates( + ASSERT_FALSE(ExtractFormDataAndProcessIBANCandidates( form_structure, /*profile_autofill_enabled=*/true, /*payment_methods_autofill_enabled=*/true)); } @@ -4569,16 +4569,16 @@ TEST_F(FormDataImporterNonParameterizedTest, ProcessCreditCardImportCandidate_EmptyCreditCard) { absl::optional<CreditCard> credit_card_import_candidate; - absl::optional<std::string> imported_upi_id; + absl::optional<std::string> extracted_upi_id; std::unique_ptr<FormStructure> form_structure = ConstructDefaultCreditCardFormStructure(); - // `form_data_importer()`'s `imported_credit_card_record_type_` is set to - // kLocalCard because we need to make sure we do not return early in the + // `form_data_importer()`'s `credit_card_import_type_` is set + // to kLocalCard because we need to make sure we do not return early in the // kNewCard case, and kLocalCard with upstream enabled but empty // |imported_credit_card| is the most likely scenario for a crash. - form_data_importer().set_imported_credit_card_record_type_for_testing( - FormDataImporter::ImportedCreditCardRecordType::kLocalCard); + form_data_importer().set_credit_card_import_type_for_testing( + FormDataImporter::CreditCardImportType::kLocalCard); // We need a sync service so that // LocalCardMigrationManager::ShouldOfferLocalCardMigration() does not crash. @@ -4586,7 +4586,7 @@ personal_data_manager_->OnSyncServiceInitialized(&sync_service); EXPECT_FALSE(form_data_importer().ProcessCreditCardImportCandidate( - *form_structure, credit_card_import_candidate, imported_upi_id, + *form_structure, credit_card_import_candidate, extracted_upi_id, /*payment_methods_autofill_enabled=*/true, /*is_credit_card_upstream_enabled=*/true)); personal_data_manager_->OnSyncServiceInitialized(nullptr); @@ -4602,12 +4602,12 @@ CreditCard::VirtualCardEnrollmentState::UNENROLLED_AND_ELIGIBLE); absl::optional<CreditCard> credit_card_import_candidate = imported_credit_card; - absl::optional<std::string> imported_upi_id; + absl::optional<std::string> extracted_upi_id; std::unique_ptr<FormStructure> form_structure = ConstructDefaultCreditCardFormStructure(); - form_data_importer().set_imported_credit_card_record_type_for_testing( - FormDataImporter::ImportedCreditCardRecordType::kServerCard); + form_data_importer().set_credit_card_import_type_for_testing( + FormDataImporter::CreditCardImportType::kServerCard); form_data_importer().SetFetchedCardInstrumentId(2222); // We need a sync service so that @@ -4621,7 +4621,7 @@ _, _, _, _)) .Times(0); EXPECT_FALSE(form_data_importer().ProcessCreditCardImportCandidate( - *form_structure, credit_card_import_candidate, imported_upi_id, + *form_structure, credit_card_import_candidate, extracted_upi_id, /*payment_methods_autofill_enabled=*/true, /*is_credit_card_upstream_enabled=*/true)); @@ -4631,7 +4631,7 @@ _, _, _, _)) .Times(1); EXPECT_TRUE(form_data_importer().ProcessCreditCardImportCandidate( - *form_structure, credit_card_import_candidate, imported_upi_id, + *form_structure, credit_card_import_candidate, extracted_upi_id, /*payment_methods_autofill_enabled=*/true, /*is_credit_card_upstream_enabled=*/true)); @@ -4650,8 +4650,8 @@ credit_card_import_candidate = test::GetCreditCard(); // Should not offer save for local cards if upstream is not enabled. - form_data_importer().set_imported_credit_card_record_type_for_testing( - FormDataImporter::ImportedCreditCardRecordType::kLocalCard); + form_data_importer().set_credit_card_import_type_for_testing( + FormDataImporter::CreditCardImportType::kLocalCard); EXPECT_FALSE(form_data_importer().ShouldOfferUploadCardOrLocalCardSave( credit_card_import_candidate, /*is_credit_card_upload_enabled=*/false)); @@ -4662,16 +4662,16 @@ /*is_credit_card_upload_enabled=*/true)); // Should not offer save for server cards. - form_data_importer().set_imported_credit_card_record_type_for_testing( - FormDataImporter::ImportedCreditCardRecordType::kServerCard); + form_data_importer().set_credit_card_import_type_for_testing( + FormDataImporter::CreditCardImportType::kServerCard); EXPECT_FALSE(form_data_importer().ShouldOfferUploadCardOrLocalCardSave( credit_card_import_candidate, /*is_credit_card_upload_enabled=*/true)); // Should always offer save for new cards; upload save if it is enabled, local // save otherwise. - form_data_importer().set_imported_credit_card_record_type_for_testing( - FormDataImporter::ImportedCreditCardRecordType::kNewCard); + form_data_importer().set_credit_card_import_type_for_testing( + FormDataImporter::CreditCardImportType::kNewCard); EXPECT_TRUE(form_data_importer().ShouldOfferUploadCardOrLocalCardSave( credit_card_import_candidate, /*is_credit_card_upload_enabled=*/true));
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager.cc b/components/autofill/core/browser/payments/local_card_migration_manager.cc index 544909fe..9bf5479 100644 --- a/components/autofill/core/browser/payments/local_card_migration_manager.cc +++ b/components/autofill/core/browser/payments/local_card_migration_manager.cc
@@ -49,20 +49,20 @@ bool LocalCardMigrationManager::ShouldOfferLocalCardMigration( const absl::optional<CreditCard>& credit_card_import_candidate, - int imported_credit_card_record_type) { - // Reset and store the imported credit card info for a later check of whether - // the imported card is supported. - imported_credit_card_number_.reset(); + int credit_card_import_type) { + // Reset and store the extracted credit card info for a later check of whether + // the extracted card is supported. + extracted_credit_card_number_.reset(); if (credit_card_import_candidate) - imported_credit_card_number_ = credit_card_import_candidate->number(); - imported_credit_card_record_type_ = imported_credit_card_record_type; + extracted_credit_card_number_ = credit_card_import_candidate->number(); + credit_card_import_type_ = credit_card_import_type; // Must be an existing card. New cards always get Upstream or local save. - switch (imported_credit_card_record_type_) { - case FormDataImporter::ImportedCreditCardRecordType::kLocalCard: + switch (credit_card_import_type_) { + case FormDataImporter::CreditCardImportType::kLocalCard: local_card_migration_origin_ = autofill_metrics::LocalCardMigrationOrigin::UseOfLocalCard; break; - case FormDataImporter::ImportedCreditCardRecordType::kServerCard: + case FormDataImporter::CreditCardImportType::kServerCard: local_card_migration_origin_ = autofill_metrics::LocalCardMigrationOrigin::UseOfServerCard; break; @@ -82,12 +82,12 @@ // Don't show the prompt if max strike count was reached. if (GetLocalCardMigrationStrikeDatabase()->ShouldBlockFeature()) { - switch (imported_credit_card_record_type_) { - case FormDataImporter::ImportedCreditCardRecordType::kLocalCard: + switch (credit_card_import_type_) { + case FormDataImporter::CreditCardImportType::kLocalCard: autofill_metrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric( AutofillMetrics::SaveTypeMetric::LOCAL); break; - case FormDataImporter::ImportedCreditCardRecordType::kServerCard: + case FormDataImporter::CreditCardImportType::kServerCard: autofill_metrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric( AutofillMetrics::SaveTypeMetric::SERVER); break; @@ -105,15 +105,15 @@ // of Upstream if there are other local cards to migrate as well. If the form // was submitted with a server card, offer migration if ANY local cards can be // migrated. - if ((imported_credit_card_record_type_ == - FormDataImporter::ImportedCreditCardRecordType::kLocalCard && + if ((credit_card_import_type_ == + FormDataImporter::CreditCardImportType::kLocalCard && migratable_credit_cards_.size() > 1) || - (imported_credit_card_record_type_ == - FormDataImporter::ImportedCreditCardRecordType::kServerCard && + (credit_card_import_type_ == + FormDataImporter::CreditCardImportType::kServerCard && !migratable_credit_cards_.empty())) { return true; - } else if (imported_credit_card_record_type_ == - FormDataImporter::ImportedCreditCardRecordType::kLocalCard && + } else if (credit_card_import_type_ == + FormDataImporter::CreditCardImportType::kLocalCard && migratable_credit_cards_.size() == 1) { autofill_metrics::LogLocalCardMigrationDecisionMetric( autofill_metrics::LocalCardMigrationDecisionMetric:: @@ -231,15 +231,15 @@ // Pops up a larger, modal dialog showing the local cards to be uploaded. ShowMainMigrationDialog(); } else { - // Check if an imported local card is listed in - // |supported_card_bin_ranges|. Abort the migration when the user uses an + // Check if an extracted local card is listed in + // `supported_card_bin_ranges`. Abort the migration when the user uses an // unsupported local card. if (!supported_card_bin_ranges.empty() && - imported_credit_card_record_type_ == - FormDataImporter::ImportedCreditCardRecordType::kLocalCard && - imported_credit_card_number_.has_value() && + credit_card_import_type_ == + FormDataImporter::CreditCardImportType::kLocalCard && + extracted_credit_card_number_.has_value() && !payments::IsCreditCardNumberSupported( - imported_credit_card_number_.value(), + extracted_credit_card_number_.value(), supported_card_bin_ranges)) { autofill_metrics::LogLocalCardMigrationDecisionMetric( autofill_metrics::LocalCardMigrationDecisionMetric::
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager.h b/components/autofill/core/browser/payments/local_card_migration_manager.h index 2a7c01d..82682125 100644 --- a/components/autofill/core/browser/payments/local_card_migration_manager.h +++ b/components/autofill/core/browser/payments/local_card_migration_manager.h
@@ -97,13 +97,13 @@ // Returns true if all of the conditions for allowing local credit card // migration are satisfied. Initializes the local card list for upload. Stores - // a local copy of |credit_card_import_candidate| and - // |imported_credit_card_record_type| locally for later check whether the - // imported card is supported. |credit_card_import_candidate| might be null if - // a user used server card. + // a local copy of `credit_card_import_candidate` and + // `credit_card_import_type` locally for later check whether + // the imported card is supported. `credit_card_import_candidate` might be + // null if a user used server card. bool ShouldOfferLocalCardMigration( const absl::optional<CreditCard>& credit_card_import_candidate, - int imported_credit_card_record_type); + int credit_card_import_type); // Called from FormDataImporter or settings page when all migration // requirements are met. Fetches legal documents and triggers the @@ -232,10 +232,10 @@ raw_ptr<PersonalDataManager> personal_data_manager_; // The imported credit card number from the form submission. - absl::optional<std::u16string> imported_credit_card_number_; + absl::optional<std::u16string> extracted_credit_card_number_; // The imported credit card record type from the form submission. - int imported_credit_card_record_type_; + int credit_card_import_type_; // Collected information about a pending migration request. payments::PaymentsClient::MigrationRequestDetails migration_request_;
diff --git a/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java b/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java index 4166aaf9..e206f5d 100644 --- a/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java +++ b/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/MediaNotificationController.java
@@ -9,7 +9,6 @@ import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.media.AudioManager; import android.os.Build; import android.os.Handler; @@ -82,11 +81,6 @@ public static final int MEDIA_ACTION_SEEK_FORWARD = 22; public static final int MEDIA_ACTION_SEEK_BACKWARD = 23; - // Overrides N detection. The production code will use |null|, which uses the Android version - // code. Otherwise, |isRunningAtLeastN()| will return whatever value is set. - @VisibleForTesting - public static Boolean sOverrideIsRunningNForTesting; - // ListenerService running for the notification. Only non-null when showing. @VisibleForTesting public Service mService; @@ -272,12 +266,6 @@ | IntentUtils.getPendingIntentMutabilityFlag(false)); } - private static boolean isRunningAtLeastN() { - return (sOverrideIsRunningNForTesting != null) - ? sOverrideIsRunningNForTesting - : Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; - } - /** * The class containing all the information for adding a button in the notification for an * action. @@ -755,17 +743,7 @@ } else if (mMediaNotificationInfo.notificationLargeIcon != null && !mMediaNotificationInfo.isPrivate) { builder.setLargeIcon(mMediaNotificationInfo.notificationLargeIcon); - } else if (!isRunningAtLeastN()) { - if (mDefaultNotificationLargeIcon == null - && mMediaNotificationInfo.defaultNotificationLargeIcon != 0) { - mDefaultNotificationLargeIcon = - MediaNotificationImageUtils.downscaleIconToIdealSize( - BitmapFactory.decodeResource(getContext().getResources(), - mMediaNotificationInfo.defaultNotificationLargeIcon)); - } - builder.setLargeIcon(mDefaultNotificationLargeIcon); } - addNotificationButtons(builder); } @@ -812,30 +790,17 @@ if (mMediaNotificationInfo.isPrivate) { // Notifications in incognito shouldn't show what is playing to avoid leaking // information. - if (isRunningAtLeastN()) { - builder.setContentTitle(getContext().getResources().getString( - R.string.media_notification_incognito)); - builder.setSubText( - getContext().getResources().getString(R.string.notification_incognito_tab)); - } else { - // App name is automatically added to the title from Android N, - // but needs to be added explicitly for prior versions. - builder.setContentTitle(mDelegate.getAppName()) - .setContentText(getContext().getResources().getString( - R.string.media_notification_incognito)); - } + builder.setContentTitle( + getContext().getResources().getString(R.string.media_notification_incognito)); + builder.setSubText( + getContext().getResources().getString(R.string.notification_incognito_tab)); return; } builder.setContentTitle(mMediaNotificationInfo.metadata.getTitle()); String artistAndAlbumText = getArtistAndAlbumText(mMediaNotificationInfo.metadata); - if (isRunningAtLeastN() || !artistAndAlbumText.isEmpty()) { - builder.setContentText(artistAndAlbumText); - builder.setSubText(mMediaNotificationInfo.origin); - } else { - // Leaving ContentText empty looks bad, so move origin up to the ContentText. - builder.setContentText(mMediaNotificationInfo.origin); - } + builder.setContentText(artistAndAlbumText); + builder.setSubText(mMediaNotificationInfo.origin); } private static String getArtistAndAlbumText(MediaMetadata metadata) {
diff --git a/components/cast_receiver/browser/embedder_application.cc b/components/cast_receiver/browser/embedder_application.cc index ae022e9..b550b03 100644 --- a/components/cast_receiver/browser/embedder_application.cc +++ b/components/cast_receiver/browser/embedder_application.cc
@@ -75,7 +75,7 @@ return nullptr; } -void EmbedderApplication::LoadPage(const GURL& gurl) { +void EmbedderApplication::NavigateToPage(const GURL& gurl) { content::WebContents* web_contents = GetWebContents(); DCHECK(web_contents); web_contents->GetController().LoadURL(gurl, content::Referrer(),
diff --git a/components/cast_receiver/browser/public/embedder_application.h b/components/cast_receiver/browser/public/embedder_application.h index c1eb31d..3e4a8aab 100644 --- a/components/cast_receiver/browser/public/embedder_application.h +++ b/components/cast_receiver/browser/public/embedder_application.h
@@ -86,7 +86,7 @@ CreateWebUIControllerFactory(std::vector<std::string> hosts); // Loads |url| in the associated WebContents. - virtual void LoadPage(const GURL& url); + virtual void NavigateToPage(const GURL& url); }; std::ostream& operator<<(std::ostream& os,
diff --git a/components/cast_receiver/browser/runtime_application_base.cc b/components/cast_receiver/browser/runtime_application_base.cc index b6abca7..b9cda54 100644 --- a/components/cast_receiver/browser/runtime_application_base.cc +++ b/components/cast_receiver/browser/runtime_application_base.cc
@@ -77,12 +77,12 @@ *embedder_application().GetWebContents()); } -void RuntimeApplicationBase::LoadPage(const GURL& url) { +void RuntimeApplicationBase::NavigateToPage(const GURL& url) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - embedder_application().LoadPage(url); + embedder_application().NavigateToPage(url); - SetWebVisibilityAndPaint(false); + SetWebVisibilityAndPaint(is_visible_); } void RuntimeApplicationBase::SetContentPermissions( @@ -104,29 +104,19 @@ } } -void RuntimeApplicationBase::OnPageLoaded() { +void RuntimeApplicationBase::OnPageNavigationComplete() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(1) << "Page loaded: " << *this; auto* window_controls = embedder_application().GetContentWindowControls(); DCHECK(window_controls); window_controls->AddVisibilityChangeObserver(*this); - if (is_touch_input_enabled_) { - window_controls->EnableTouchInput(); - } else { - window_controls->DisableTouchInput(); - } - - // Create the window and show the web view. - if (is_visible_) { - DVLOG(1) << "Loading page in full screen: " << *this; - window_controls->ShowWindow(); - } else { - DVLOG(1) << "Loading page in background: " << *this; - window_controls->HideWindow(); - } embedder_application().NotifyApplicationStarted(); + + SetWebVisibilityAndPaint(is_visible_); + SetTouchInputEnabled(is_touch_input_enabled_); + SetMediaBlocking(is_media_load_blocked_, is_media_start_blocked_); } void RuntimeApplicationBase::SetUrlRewriteRules( @@ -139,7 +129,12 @@ url_rewrite::UrlRequestRewriteRulesManager& url_request_rewrite_rules_manager = GetApplicationControls().GetUrlRequestRewriteRulesManager(); - url_request_rewrite_rules_manager.OnRulesUpdated(std::move(mojom_rules)); + if (!url_request_rewrite_rules_manager.OnRulesUpdated( + std::move(mojom_rules))) { + LOG(ERROR) << "URL rewrite rules update failed."; + StopApplication(EmbedderApplication::ApplicationStopReason::kRuntimeError, + net::Error::ERR_UNEXPECTED); + } } void RuntimeApplicationBase::SetMediaBlocking(bool load_blocked, @@ -242,6 +237,15 @@ if (is_visible) { web_contents->WasShown(); } else { + // NOTE: Calling WasHidden() and later WasShown() does not behave properly + // on some platforms (e.g. Linux devices using X11 platform for Ozone). In + // such cases, the WasShown() call will execute, and the browser-side code + // associated with this call will run, but it will never reach the Renderer + // process, so the LayerTreeHost will never draw the surface assocaited with + // this WebContents. + DLOG(WARNING) + << "WebContents hidden. NOTE: Changing from hidden to visible does not " + "work in all cases, and such calls may not be respected."; web_contents->WasHidden(); }
diff --git a/components/cast_receiver/browser/runtime_application_base.h b/components/cast_receiver/browser/runtime_application_base.h index 5fd5211..feac3156 100644 --- a/components/cast_receiver/browser/runtime_application_base.h +++ b/components/cast_receiver/browser/runtime_application_base.h
@@ -86,11 +86,12 @@ ApplicationClient& application_client() { return *application_client_; } - // Loads the page at the given |url| in the associated WebContents. - void LoadPage(const GURL& url); + // Navigated to the page at the given |url| in the associated WebContents. + void NavigateToPage(const GURL& url); - // Called by the actual implementation as Cast application page has loaded. - void OnPageLoaded(); + // Called by the actual implementation after the Cast application page has + // been navigated to, following a call to NavigateToPage(). + void OnPageNavigationComplete(); // Sets the permissions for the provided |web_contents| to that as configured // in |app_config_|.
diff --git a/components/cast_receiver/browser/streaming_runtime_application.cc b/components/cast_receiver/browser/streaming_runtime_application.cc index 5e437b2..cc18fac5b 100644 --- a/components/cast_receiver/browser/streaming_runtime_application.cc +++ b/components/cast_receiver/browser/streaming_runtime_application.cc
@@ -43,7 +43,7 @@ void StreamingRuntimeApplication::OnStreamingSessionStarted() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - OnPageLoaded(); + OnPageNavigationComplete(); } void StreamingRuntimeApplication::OnError() { @@ -86,7 +86,7 @@ receiver_session_client_->LaunchStreamingReceiverAsync(); // Application is initialized now - we can load the URL. - LoadPage(GURL(base::StringPrintf( + NavigateToPage(GURL(base::StringPrintf( kStreamingPageUrlTemplate, cast_streaming::GetCastStreamingMediaSourceUrl().spec().c_str())));
diff --git a/components/cast_receiver/browser/web_runtime_application.cc b/components/cast_receiver/browser/web_runtime_application.cc index 3fba9a6..1ee9cf3 100644 --- a/components/cast_receiver/browser/web_runtime_application.cc +++ b/components/cast_receiver/browser/web_runtime_application.cc
@@ -127,12 +127,12 @@ embedder_application().GetWebContents()); // Application is initialized now - we can load the URL. - LoadPage(app_url()); + NavigateToPage(app_url()); } void WebRuntimeApplication::OnPageLoadComplete() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - OnPageLoaded(); + OnPageNavigationComplete(); } void WebRuntimeApplication::OnError() {
diff --git a/components/exo/wayland/zaura_shell.cc b/components/exo/wayland/zaura_shell.cc index 1007657..e6e970a 100644 --- a/components/exo/wayland/zaura_shell.cc +++ b/components/exo/wayland/zaura_shell.cc
@@ -1082,6 +1082,7 @@ 1352584, 1358908, 1400226, + 1402158, }; // Implements aura shell interface and monitors workspace state needed
diff --git a/components/language/content/browser/geo_language_provider.cc b/components/language/content/browser/geo_language_provider.cc index 9bb3678..40f83b9 100644 --- a/components/language/content/browser/geo_language_provider.cc +++ b/components/language/content/browser/geo_language_provider.cc
@@ -218,11 +218,11 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(creation_sequence_checker_); languages_ = languages; - base::ListValue cache_list; + base::Value::List cache_list; for (const std::string& language : languages_) { cache_list.Append(language); } - prefs_->Set(kCachedGeoLanguagesPref, cache_list); + prefs_->SetList(kCachedGeoLanguagesPref, std::move(cache_list)); prefs_->SetDouble(kTimeOfLastGeoLanguagesUpdatePref, base::Time::Now().ToDoubleT()); }
diff --git a/components/language/content/browser/geo_language_provider_unittest.cc b/components/language/content/browser/geo_language_provider_unittest.cc index 154d0d5..5e2c785 100644 --- a/components/language/content/browser/geo_language_provider_unittest.cc +++ b/components/language/content/browser/geo_language_provider_unittest.cc
@@ -65,11 +65,12 @@ void SetUpCachedLanguages(const std::vector<std::string>& languages, const double update_time) { - base::ListValue cache_list; + base::Value::List cache_list; for (const std::string& language : languages) { cache_list.Append(language); } - local_state_.Set(GeoLanguageProvider::kCachedGeoLanguagesPref, cache_list); + local_state_.SetList(GeoLanguageProvider::kCachedGeoLanguagesPref, + std::move(cache_list)); local_state_.SetDouble( GeoLanguageProvider::kTimeOfLastGeoLanguagesUpdatePref, update_time); }
diff --git a/components/lens/lens_entrypoints.h b/components/lens/lens_entrypoints.h index a677f7f..88591a9 100644 --- a/components/lens/lens_entrypoints.h +++ b/components/lens/lens_entrypoints.h
@@ -13,7 +13,6 @@ CHROME_REGION_SEARCH_MENU_ITEM, CHROME_SEARCH_WITH_GOOGLE_LENS_CONTEXT_MENU_ITEM, CHROME_FULLSCREEN_SEARCH_MENU_ITEM, - CHROME_SCREENSHOT_SEARCH, UNKNOWN };
diff --git a/components/lens/lens_features.cc b/components/lens/lens_features.cc index 94dc116..9e01cb7 100644 --- a/components/lens/lens_features.cc +++ b/components/lens/lens_features.cc
@@ -22,10 +22,6 @@ "LensSearchOptimizations", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kLensSearchImageInScreenshotSharing, - "LensSearchImageInScreenshotSharing", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kEnableLatencyLogging, "LensImageLatencyLogging", base::FEATURE_ENABLED_BY_DEFAULT); @@ -70,13 +66,6 @@ constexpr base::FeatureParam<int> kMaxPixelsForImageSearch{ &kLensImageCompression, "dimensions-max-pixels", 1000}; -const base::FeatureParam<bool> kUseSidePanelForScreenshotSharing{ - &kLensSearchImageInScreenshotSharing, - "use-side-panel-for-screenshot-sharing", false}; - -const base::FeatureParam<bool> kEnablePersistentBubble{ - &kLensSearchImageInScreenshotSharing, "enable-persistent-bubble", false}; - const base::FeatureParam<bool> kEnableLensFullscreenSearch{ &kLensSearchOptimizations, "enable-lens-fullscreen-search", true}; @@ -147,23 +136,6 @@ return IsLensSidePanelEnabled() && !IsLensFullscreenSearchEnabled(); } -bool IsLensInScreenshotSharingEnabled() { - return base::FeatureList::IsEnabled(kLensStandalone) && - base::FeatureList::IsEnabled(kLensSearchImageInScreenshotSharing); -} - -// Does not check if kLensSearchImageInScreenshotSharing is enabled because this -// method is not called if kLensSearchImageInScreenshotSharing is false -bool UseSidePanelForScreenshotSharing() { - return kUseSidePanelForScreenshotSharing.Get(); -} - -// Does not check if kLensSearchImageInScreenshotSharing is enabled because this -// method is not called if kLensSearchImageInScreenshotSharing is false -bool EnablePersistentBubble() { - return kEnablePersistentBubble.Get(); -} - bool IsLensRegionSearchStaticPageEnabled() { return base::FeatureList::IsEnabled(kLensRegionSearchStaticPage); }
diff --git a/components/lens/lens_features.h b/components/lens/lens_features.h index 43a0bc1..df6c086 100644 --- a/components/lens/lens_features.h +++ b/components/lens/lens_features.h
@@ -27,11 +27,6 @@ COMPONENT_EXPORT(LENS_FEATURES) BASE_DECLARE_FEATURE(kLensSearchOptimizations); -// Enables Lens integration into the Chrome screenshot sharing feature by adding -// a "Search Image" button. -COMPONENT_EXPORT(LENS_FEATURES) -BASE_DECLARE_FEATURE(kLensSearchImageInScreenshotSharing); - // Enables Latency logging for the LensStandalone feature. COMPONENT_EXPORT(LENS_FEATURES) BASE_DECLARE_FEATURE(kEnableLatencyLogging); @@ -40,11 +35,6 @@ COMPONENT_EXPORT(LENS_FEATURES) BASE_DECLARE_FEATURE(kEnableRegionSearchKeyboardShortcut); -// Enables the modification of the instruction chip UI that is presented when -// region search is opened. -COMPONENT_EXPORT(LENS_FEATURES) -BASE_DECLARE_FEATURE(kLensInstructionChipImprovements); - // Enables the image search side panel experience for third party default search // engines COMPONENT_EXPORT(LENS_FEATURES) @@ -58,23 +48,6 @@ COMPONENT_EXPORT(LENS_FEATURES) BASE_DECLARE_FEATURE(kLensImageFormatOptimizations); -// Enables using `Google` as the visual search provider instead of `Google -// Lens`. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kUseGoogleAsVisualSearchProvider; - -// Enables alternate option 1 for the Region Search context menu item text. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kRegionSearchUseMenuItemAltText1; - -// Enables alternate option 2 for the Region Search context menu item text. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kRegionSearchUseMenuItemAltText2; - -// Enables alternate option 3 for the Region Search context menu item text. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kRegionSearchUseMenuItemAltText3; - // Enables UKM logging for the Lens Region Search feature. COMPONENT_EXPORT(LENS_FEATURES) extern const base::FeatureParam<bool> kEnableUKMLoggingForRegionSearch; @@ -99,25 +72,6 @@ COMPONENT_EXPORT(LENS_FEATURES) extern const base::FeatureParam<bool> kEnableFullscreenSearch; -// Enables using side panel in the Chrome Screenshot sharing feature integration -// instead of a new tab. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kUseSidePanelForScreenshotSharing; - -// Forces the Chrome Screenshot sharing dialog bubble to stay open after the -// user clicks the Search Image button. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kEnablePersistentBubble; - -// Enables the use of the selection with image icon when using the instruction -// chip improvements feature. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kUseSelectionIconWithImage; - -// Enables the use of an alternative string for the instruction chip. -COMPONENT_EXPORT(LENS_FEATURES) -extern const base::FeatureParam<bool> kUseAltChipString; - // Enables encoding to WebP for image search queries. COMPONENT_EXPORT(LENS_FEATURES) extern const base::FeatureParam<bool> kUseWebpInImageSearch; @@ -183,27 +137,6 @@ // Returns whether Lens fullscreen search is enabled. COMPONENT_EXPORT(LENS_FEATURES) extern bool IsLensFullscreenSearchEnabled(); - -// Returns whether to use alternative option 1 for the Region Search context -// menu item text. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseRegionSearchMenuItemAltText1(); - -// Returns whether to use alternative option 2 for the Region Search context -// menu item text. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseRegionSearchMenuItemAltText2(); - -// Returns whether to use alternative option 3 for the Region Search context -// menu item text. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseRegionSearchMenuItemAltText3(); - -// Returns whether to use `Google` as the visual search provider for all -// relevant Lens context menu strings. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseGoogleAsVisualSearchProvider(); - // Returns whether the Lens side panel is enabled for image search. COMPONENT_EXPORT(LENS_FEATURES) extern bool IsLensSidePanelEnabled(); @@ -217,29 +150,6 @@ COMPONENT_EXPORT(LENS_FEATURES) extern bool IsLensInScreenshotSharingEnabled(); -// Returns whether the instruction chip improvement feature is enabled. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool IsLensInstructionChipImprovementsEnabled(); - -// Returns whether to use the Chrome Side Panel for the Lens integration in -// Chrome Screenshot Sharing feature -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseSidePanelForScreenshotSharing(); - -// Returns whether the Chrome Screenshot Sharing Bubble disappears after the -// user clicks the Search Image button -COMPONENT_EXPORT(LENS_FEATURES) -extern bool EnablePersistentBubble(); - -// Returns if we should use the selection with image icon instead of the default -// when using the instruction chip improvements feature. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseSelectionIconWithImage(); - -// Returns whether we should use an alternative instruction chip string. -COMPONENT_EXPORT(LENS_FEATURES) -extern bool UseAltChipString(); - // Returns whether we should use a WebUI static page for region search. COMPONENT_EXPORT(LENS_FEATURES) extern bool IsLensRegionSearchStaticPageEnabled();
diff --git a/components/lens/lens_url_utils.cc b/components/lens/lens_url_utils.cc index 5afd38e..89513f1 100644 --- a/components/lens/lens_url_utils.cc +++ b/components/lens/lens_url_utils.cc
@@ -25,7 +25,6 @@ constexpr char kChromeSearchWithGoogleLensContextMenuItem[] = "ccm"; constexpr char kChromeOpenNewTabSidePanel[] = "cnts"; constexpr char kChromeFullscreenSearchMenuItem[] = "cfs"; -constexpr char kChromeScreenshotSearch[] = "css"; constexpr char kSurfaceQueryParameter[] = "s"; constexpr char kStartTimeQueryParameter[] = "st"; @@ -68,10 +67,6 @@ query_parameters.insert( {kEntryPointQueryParameter, kChromeFullscreenSearchMenuItem}); break; - case lens::CHROME_SCREENSHOT_SEARCH: - query_parameters.insert( - {kEntryPointQueryParameter, kChromeScreenshotSearch}); - break; default: // Empty strings are ignored when query parameters are built. break; @@ -159,4 +154,4 @@ return query_string; } -} // namespace lens \ No newline at end of file +} // namespace lens
diff --git a/components/lens/lens_url_utils_unittest.cc b/components/lens/lens_url_utils_unittest.cc index ccf686e5..a66ad70 100644 --- a/components/lens/lens_url_utils_unittest.cc +++ b/components/lens/lens_url_utils_unittest.cc
@@ -70,14 +70,6 @@ EXPECT_THAT(query_param, MatchesRegex("ep=cfs&re=avsf&s=&st=\\d+")); } -TEST(LensUrlUtilsTest, GetScreenshotSearchQueryParameterTest) { - lens::EntryPoint lens_ep = lens::EntryPoint::CHROME_SCREENSHOT_SEARCH; - std::string query_param = lens::GetQueryParametersForLensRequest( - lens_ep, /* is_side_panel_request= */ false, - /* is_full_screen_region_search_request= */ false); - EXPECT_THAT(query_param, MatchesRegex("ep=css&re=df&s=&st=\\d+")); -} - TEST(LensUrlUtilsTest, GetUnknownEntryPointTest) { std::string query_param = lens::GetQueryParametersForLensRequest( lens::EntryPoint::UNKNOWN, /* is_side_panel_request= */ false, @@ -163,16 +155,6 @@ EXPECT_THAT(url.query(), MatchesRegex("ep=cfs&re=avsf&s=&st=\\d+")); } -TEST(LensUrlUtilsTest, AppendScreenshotSearchQueryParameterTest) { - lens::EntryPoint lens_ep = lens::EntryPoint::CHROME_SCREENSHOT_SEARCH; - lens::RenderingEnvironment re = - lens::RenderingEnvironment::ONELENS_DESKTOP_WEB_FULLSCREEN; - GURL original_url = GURL("https://lens.google.com/"); - GURL url = lens::AppendOrReplaceQueryParametersForLensRequest( - original_url, lens_ep, re, /* is_side_panel_request= */ false); - EXPECT_THAT(url.query(), MatchesRegex("ep=css&re=df&s=&st=\\d+")); -} - TEST(LensUrlUtilsTest, AppendUnknownEntryPointTest) { lens::RenderingEnvironment re = lens::RenderingEnvironment::ONELENS_DESKTOP_WEB_FULLSCREEN;
diff --git a/components/omnibox/browser/autocomplete_grouper_sections.cc b/components/omnibox/browser/autocomplete_grouper_sections.cc index a3b2ef26..62558802 100644 --- a/components/omnibox/browser/autocomplete_grouper_sections.cc +++ b/components/omnibox/browser/autocomplete_grouper_sections.cc
@@ -4,6 +4,9 @@ #include "components/omnibox/browser/autocomplete_grouper_sections.h" +#include <algorithm> +#include <iterator> +#include <limits> #include <memory> #include "base/ranges/algorithm.h" @@ -17,11 +20,12 @@ // static ACMatches Section::GroupMatches(PSections sections, ACMatches matches) { - int last_relevance = -1; + int last_relevance = std::numeric_limits<int>::max(); for (const auto& match : matches) { DCHECK(match.suggestion_group_id.has_value()); - DCHECK(last_relevance == -1 || match.relevance <= last_relevance); - last_relevance = match.relevance; + DCHECK(match.relevance <= last_relevance); + if (!match.allowed_to_be_default_match) + last_relevance = match.relevance; for (const auto& section : sections) { if (section->Add(match)) break; @@ -79,21 +83,32 @@ groups_.push_back(std::make_unique<MultiGroup>( 7, MultiGroup::GroupLimitsAndCounts{{omnibox::GROUP_OTHER_NAVS, {7, 0}}})); + // The default values above are reasonable placeholders. Iterate `matches` to + // determine the actual limits. + // Determine if `matches` contains any searches. bool has_search = base::ranges::any_of( matches, [&](const auto& match) { return groups_[1]->CanAdd(match); }); + // Determine if the default match will be a search. auto default_match = base::ranges::find_if( matches, [&](const auto& match) { return groups_[0]->CanAdd(match); }); bool default_is_search = default_match != matches.end() && groups_[1]->CanAdd(*default_match); + // Find the 1st nav's index. + size_t first_nav_index = std::distance( + matches.begin(), base::ranges::find_if(matches, [&](const auto& match) { + return groups_[2]->CanAdd(match); + })); + + // Show at most 8 suggestions if doing so includes navs; otherwise show 9 or + // 10, if doing so doesn't include navs. + limit_ = std::clamp<size_t>(first_nav_index, 8, 10); + groups_[1]->limit_ = limit_ - 1; + groups_[2]->limit_ = limit_ - 1; + + // Show at least 1 search, either in the default group or the search group. if (has_search && !default_is_search) groups_[2]->limit_--; } - -GroupBase* DesktopNonZpsSection::CanAdd(const AutocompleteMatch& match) { - if (groups_[2]->CanAdd(match)) - limit_ = 8; - return Section::CanAdd(match); -}
diff --git a/components/omnibox/browser/autocomplete_grouper_sections.h b/components/omnibox/browser/autocomplete_grouper_sections.h index 6ac0c69..12edf5d 100644 --- a/components/omnibox/browser/autocomplete_grouper_sections.h +++ b/components/omnibox/browser/autocomplete_grouper_sections.h
@@ -60,7 +60,6 @@ class DesktopNonZpsSection : public Section { public: explicit DesktopNonZpsSection(const ACMatches& matches); - GroupBase* CanAdd(const AutocompleteMatch& match) override; }; #endif // COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_GROUPER_SECTIONS_H_
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 8b46e8e..d0926c1 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -31,6 +31,7 @@ #include "components/search_engines/template_url_service.h" #include "inline_autocompletion_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "third_party/omnibox_proto/groups.pb.h" #include "ui/gfx/vector_icon_types.h" #include "url/third_party/mozilla/url_parse.h" @@ -807,6 +808,31 @@ } // static +omnibox::GroupId AutocompleteMatch::GetDefaultGroupId(Type type) { + if (type == AutocompleteMatchType::TILE_NAVSUGGEST || + type == AutocompleteMatchType::TILE_SUGGESTION) { + return omnibox::GROUP_MOBILE_MOST_VISITED; + } + + if (type == AutocompleteMatchType::CLIPBOARD_URL || + type == AutocompleteMatchType::CLIPBOARD_TEXT || + type == AutocompleteMatchType::CLIPBOARD_IMAGE) { + return omnibox::GROUP_MOBILE_CLIPBOARD; + } + + if (IsStarterPackType(type)) + return omnibox::GROUP_STARTER_PACK; + + if (IsSearchType(type)) + return omnibox::GROUP_SEARCH; + + if (type == AutocompleteMatchType::HISTORY_CLUSTER) + return omnibox::GROUP_HISTORY_CLUSTER; + + return omnibox::GROUP_OTHER_NAVS; +} + +// static TemplateURL* AutocompleteMatch::GetTemplateURLWithKeyword( TemplateURLService* template_url_service, const std::u16string& keyword,
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h index cf5d63f..f86ef7f 100644 --- a/components/omnibox/browser/autocomplete_match.h +++ b/components/omnibox/browser/autocomplete_match.h
@@ -354,6 +354,10 @@ // clipboard or query tile. static bool ShouldBeSkippedForGroupBySearchVsUrl(Type type); + // Return a group ID based on type. Should only be used as a fill in for + // matches that don't already have a group ID set by providers. + static omnibox::GroupId GetDefaultGroupId(Type type); + // A static version GetTemplateURL() that takes the match's keyword and // match's hostname as parameters. In short, returns the TemplateURL // associated with |keyword| if it exists; otherwise returns the TemplateURL
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc index 9c0074c..ed74171 100644 --- a/components/omnibox/browser/autocomplete_result.cc +++ b/components/omnibox/browser/autocomplete_result.cc
@@ -27,6 +27,7 @@ #include "components/history_clusters/core/config.h" #include "components/omnibox/browser/actions/omnibox_pedal.h" #include "components/omnibox/browser/actions/omnibox_pedal_provider.h" +#include "components/omnibox/browser/autocomplete_grouper_sections.h" #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_match_type.h" #include "components/omnibox/browser/autocomplete_provider.h" @@ -355,82 +356,101 @@ matches_[0].ComputeStrippedDestinationURL(input, template_url_service); } - // TODO(manukh): Limiting (history clusters, zero suggest, max URL - // suggestions, max suggestions, and max keyword suggestions) should be done - // by the grouping framework. - // Limit history cluster suggestions to 1. This has to be done before limiting - // URL matches below so that a to-be-removed history cluster suggestion - // doesn't waste a URL slot. - bool history_cluster_included = false; - base::EraseIf(matches_, [&](const auto& match) { - // If not a history cluster match, don't erase it. - if (match.type != AutocompleteMatch::Type::HISTORY_CLUSTER) - return false; - // If not the 1st history cluster match, do erase it. - if (history_cluster_included) - return true; - // If the 1st history cluster match, don't erase it. - history_cluster_included = true; - return false; - }); - - // Limit URL matches per OmniboxMaxURLMatches. - size_t max_url_count = 0; + // If `kGroupingFramework` is enabled and the current input & platform are + // supported, delegate to the framework. const bool is_zero_suggest = input.IsZeroSuggest(); - if (OmniboxFieldTrial::IsMaxURLMatchesFeatureEnabled() && - (max_url_count = OmniboxFieldTrial::GetMaxURLMatches()) != 0) - LimitNumberOfURLsShown(GetMaxMatches(is_zero_suggest), max_url_count, - comparing_object); - - // Limit total matches accounting for suggestions score <= 0, sub matches, and - // feature configs such as OmniboxUIExperimentMaxAutocompleteMatches, - // OmniboxMaxZeroSuggestMatches, and OmniboxDynamicMaxAutocomplete. - const size_t num_matches = - CalculateNumMatches(is_zero_suggest, matches_, comparing_object); - - // Group and trim suggestions to the given limit. - if (!is_zero_suggest) { - // Until limits are applied by the grouping framework, typed suggestions are - // trimmed then grouped. - // TODO(manukh): Limiting should be done by the grouping framework. - matches_.resize(num_matches); - - // Group search suggestions above URL suggestions. - if (matches_.size() > 2 && - !base::FeatureList::IsEnabled(omnibox::kAdaptiveSuggestionsCount)) { - // TODO(manukh): Grouping search v URL (actually - // `GroupSuggestionsBySearchVsURL` now groups by other types as well) - // should be done by the grouping framework. - GroupSuggestionsBySearchVsURL(std::next(matches_.begin()), - matches_.end()); - } - GroupAndDemoteMatchesInGroups(); - - } else if (base::FeatureList::IsEnabled(omnibox::kKeepSecondaryZeroSuggest)) { - // Until limits are applied by the grouping framework, zero-prefix - // suggestions are grouped then trimmed. - // TODO(manukh): Limiting should be done by the grouping framework. - GroupAndDemoteMatchesInGroups(); - size_t num_primary_suggestions = 0; - base::EraseIf(matches_, [&](const auto& match) { - if (!match.suggestion_group_id.has_value() || - GetSideTypeForSuggestionGroup(match.suggestion_group_id.value()) == - omnibox::GroupConfig_SideType_DEFAULT_PRIMARY) { - // Trim the primary suggestions to the given limit. - return ++num_primary_suggestions > num_matches; - } else { - // Keep the secondary suggestions for the NTP realbox. - // TODO(ender): Add appropriate page classification for Android. - return page_classification != OmniboxEventProto::NTP_REALBOX; + if (base::FeatureList::IsEnabled(omnibox::kGroupingFramework) && + !is_zero_suggest && !is_android && !is_ios) { + // Grouping requires all matches have a group ID. To keep providers 'dumb', + // they only assign IDs when their ID isn't obvious from the match type. + // Most matches will instead set IDs here to keep providers 'dumb' and the + // type->group mapping consistent between providers. + base::ranges::for_each(matches_, [&](auto& match) { + if (!match.suggestion_group_id.has_value()) { + match.suggestion_group_id = + AutocompleteMatch::GetDefaultGroupId(match.type); } + DCHECK(match.suggestion_group_id.has_value()); }); + // Some providers give 0 relevance matches that are meant for deduping only + // but shouldn't be shown otherwise. Filter them out. + base::EraseIf(matches_, + [&](const auto& match) { return match.relevance == 0; }); + + // If there's only 1 match, then grouping is a no-op. + if (matches_.size() > 2) { + PSections sections; + sections.push_back(std::make_unique<DesktopNonZpsSection>(matches_)); + matches_ = Section::GroupMatches(std::move(sections), matches_); + } + } else { - // Until limits are applied by the grouping framework, zero-prefix - // suggestions are grouped then trimmed. - // TODO(manukh): Limiting should be done by the grouping framework. - GroupAndDemoteMatchesInGroups(); - matches_.resize(num_matches); + // Limit history cluster suggestions to 1. This has to be done before + // limiting URL matches below so that a to-be-removed history cluster + // suggestion doesn't waste a URL slot. + bool history_cluster_included = false; + base::EraseIf(matches_, [&](const auto& match) { + // If not a history cluster match, don't erase it. + if (match.type != AutocompleteMatch::Type::HISTORY_CLUSTER) + return false; + // If not the 1st history cluster match, do erase it. + if (history_cluster_included) + return true; + // If the 1st history cluster match, don't erase it. + history_cluster_included = true; + return false; + }); + + // Limit URL matches per OmniboxMaxURLMatches. + size_t max_url_count = 0; + if (OmniboxFieldTrial::IsMaxURLMatchesFeatureEnabled() && + (max_url_count = OmniboxFieldTrial::GetMaxURLMatches()) != 0) + LimitNumberOfURLsShown(GetMaxMatches(is_zero_suggest), max_url_count, + comparing_object); + + // Limit total matches accounting for suggestions score <= 0, sub matches, + // and feature configs such as OmniboxUIExperimentMaxAutocompleteMatches, + // OmniboxMaxZeroSuggestMatches, and OmniboxDynamicMaxAutocomplete. + const size_t num_matches = + CalculateNumMatches(is_zero_suggest, matches_, comparing_object); + + // Group and trim suggestions to the given limit. + if (!is_zero_suggest) { + // Typed suggestions are trimmed then grouped. + matches_.resize(num_matches); + + // Group search suggestions above URL suggestions. + if (matches_.size() > 2 && + !base::FeatureList::IsEnabled(omnibox::kAdaptiveSuggestionsCount)) { + GroupSuggestionsBySearchVsURL(std::next(matches_.begin()), + matches_.end()); + } + GroupAndDemoteMatchesInGroups(); + + } else if (base::FeatureList::IsEnabled( + omnibox::kKeepSecondaryZeroSuggest)) { + // Zero-prefix suggestions are grouped then trimmed. + GroupAndDemoteMatchesInGroups(); + size_t num_primary_suggestions = 0; + base::EraseIf(matches_, [&](const auto& match) { + if (!match.suggestion_group_id.has_value() || + GetSideTypeForSuggestionGroup(match.suggestion_group_id.value()) == + omnibox::GroupConfig_SideType_DEFAULT_PRIMARY) { + // Trim the primary suggestions to the given limit. + return ++num_primary_suggestions > num_matches; + } else { + // Keep the secondary suggestions for the NTP realbox. + // TODO(ender): Add appropriate page classification for Android. + return page_classification != OmniboxEventProto::NTP_REALBOX; + } + }); + + } else { + // Zero-prefix suggestions are grouped then trimmed. + GroupAndDemoteMatchesInGroups(); + matches_.resize(num_matches); + } } #if DCHECK_IS_ON()
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index ff997d2..ef33226 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -73,11 +73,10 @@ "OmniboxDocumentProviderDedupingOptimization", base::FEATURE_ENABLED_BY_DEFAULT); -// Feature to tweak how the default suggestion is preserved. Feature params -// control which tweaks specifically are enabled. Enabling this feature without -// params is a no-op. -BASE_FEATURE(kPreserveDefault, - "OmniboxPreserveDefault", +// When enabled, uses the grouping framework (i.e. +// autocomplete_grouper_sections.h) to limit and group (but not sort) matches. +BASE_FEATURE(kGroupingFramework, + "OmniboxGroupingFramework", base::FEATURE_DISABLED_BY_DEFAULT); // Demotes the relevance scores when comparing suggestions based on the @@ -94,6 +93,20 @@ "OmniboxRemoveExcessiveRecycledViewClearCalls", base::FEATURE_DISABLED_BY_DEFAULT); +// Feature to tweak how the default suggestion is preserved. Feature params +// control which tweaks specifically are enabled. Enabling this feature without +// params is a no-op. +BASE_FEATURE(kPreserveDefault, + "OmniboxPreserveDefault", + base::FEATURE_DISABLED_BY_DEFAULT); + +// When disabled, when providers update their matches, the new set of matches +// are sorted and culled, then merged with the old matches, then sorted and +// culled again. When enabled, the first sort and cull is skipped. +BASE_FEATURE(kSingleSortAndCullPass, + "OmniboxSingleSortAndCullPass", + base::FEATURE_DISABLED_BY_DEFAULT); + // Feature to enable memoizing URLs when replacing search terms in // `AutocompleteMatch::GURLToStrippedGURL()`. // TODO(manukh) Enabled by default on 10/20/22 m109. Clean up feature code @@ -107,13 +120,6 @@ "OmniboxUpdateResultDebounce", base::FEATURE_DISABLED_BY_DEFAULT); -// When disabled, when providers update their matches, the new set of matches -// are sorted and culled, then merged with the old matches, then sorted and -// culled again. When enabled, the first sort and cull is skipped. -BASE_FEATURE(kSingleSortAndCullPass, - "OmniboxSingleSortAndCullPass", - base::FEATURE_DISABLED_BY_DEFAULT); - // Feature used to cap max zero suggestions shown according to the param // OmniboxMaxZeroSuggestMatches. If omitted, // OmniboxUIExperimentMaxAutocompleteMatches will be used instead. If present,
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index efd9148..10350ef 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -21,12 +21,13 @@ // `SortAndCull()`. BASE_DECLARE_FEATURE(kAutocompleteStability); BASE_DECLARE_FEATURE(kDocumentProviderDedupingOptimization); +BASE_DECLARE_FEATURE(kGroupingFramework); BASE_DECLARE_FEATURE(kOmniboxDemoteByType); BASE_DECLARE_FEATURE(kOmniboxRemoveExcessiveRecycledViewClearCalls); BASE_DECLARE_FEATURE(kPreserveDefault); +BASE_DECLARE_FEATURE(kSingleSortAndCullPass); BASE_DECLARE_FEATURE(kStrippedGurlOptimization); BASE_DECLARE_FEATURE(kUpdateResultDebounce); -BASE_DECLARE_FEATURE(kSingleSortAndCullPass); // Features below this line should be sorted alphabetically by their comments.
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc index a50b297..5c88d81c 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -79,6 +79,9 @@ namespace { +using RectId = PageAdDensityTracker::RectId; +using RectType = PageAdDensityTracker::RectType; + #define ADS_HISTOGRAM(suffix, hist_macro, visibility, value) \ switch (visibility) { \ case kNonVisible: \ @@ -639,11 +642,19 @@ FrameTreeData* ancestor_data = FindFrameData(frame_tree_node_id); if (ancestor_data && frame_tree_node_id == ancestor_data->root_frame_tree_node_id()) { - page_ad_density_tracker_.RemoveRect(frame_tree_node_id); + RectId rect_id = RectId(RectType::kIFrame, frame_tree_node_id); + // Only add frames if they are visible. if (!ancestor_data->is_display_none()) { - page_ad_density_tracker_.AddRect(frame_tree_node_id, - main_frame_intersection_rect); + page_ad_density_tracker_.RemoveRect( + rect_id, + /*recalculate_viewport_density=*/false); + page_ad_density_tracker_.AddRect(rect_id, main_frame_intersection_rect, + /*recalculate_density=*/true); + } else { + page_ad_density_tracker_.RemoveRect( + rect_id, + /*recalculate_viewport_density=*/true); } } @@ -656,6 +667,12 @@ main_frame_viewport_rect); } +void AdsPageLoadMetricsObserver::OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) { + page_ad_density_tracker_.UpdateMainFrameImageAdRects( + main_frame_image_ad_rects); +} + // TODO(https://crbug.com/1142669): Evaluate imposing width requirements // for ad density violations. void AdsPageLoadMetricsObserver::CheckForAdDensityViolation() { @@ -850,8 +867,8 @@ auto* ukm_recorder = ukm::UkmRecorder::Get(); - // AdPageLoadCustomSampling2 is recorded on all pages - ukm::builders::AdPageLoadCustomSampling2 custom_sampling_builder(source_id); + // AdPageLoadCustomSampling3 is recorded on all pages + ukm::builders::AdPageLoadCustomSampling3 custom_sampling_builder(source_id); page_ad_density_tracker_.Finalize(); @@ -1450,8 +1467,10 @@ if (record_metrics) RecordPerFrameMetrics(*frame_data, GetDelegate().GetPageUkmSourceId()); - if (update_density_tracker) - page_ad_density_tracker_.RemoveRect(id); + if (update_density_tracker) { + page_ad_density_tracker_.RemoveRect(RectId(RectType::kIFrame, id), + /*recalculate_viewport_density=*/true); + } } } // namespace page_load_metrics
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h index b194d64..3b59a045 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h +++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -137,6 +137,8 @@ const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) override; void OnSubFrameDeleted(int frame_tree_node_id) override; void OnV8MemoryChanged( const std::vector<MemoryUpdate>& memory_updates) override;
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc index 1d37a29..27f5f9e 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc +++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc
@@ -1712,24 +1712,24 @@ NavigateFrame(kNonAdUrl, main_frame); auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdPageLoadCustomSampling2::kEntryName); + ukm::builders::AdPageLoadCustomSampling3::kEntryName); EXPECT_EQ(1u, entries.size()); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kAverageViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kAverageViewportAdDensityName, 20); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kVarianceViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kVarianceViewportAdDensityName, /*ukm::GetExponentialBucketMin(300, 1.3)=*/248); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kSkewnessViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kSkewnessViewportAdDensityName, /*ukm::GetExponentialBucketMin(std::llround(1.1547), 1.3)=*/1); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kKurtosisViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kKurtosisViewportAdDensityName, /*-ukm::GetExponentialBucketMin(-std::llround(-0.666667), 1.3)=*/-1); } @@ -1740,7 +1740,7 @@ RenderFrameHost* main_frame = NavigateMainFrame(kNonAdUrl); - // No ad resource so that only AdPageLoadCustomSampling2 is recorded in the + // No ad resource so that only AdPageLoadCustomSampling3 is recorded in the // end. AdvancePageDuration(base::Seconds(1)); @@ -1748,23 +1748,23 @@ NavigateFrame(kNonAdUrl, main_frame); auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::AdPageLoadCustomSampling2::kEntryName); + ukm::builders::AdPageLoadCustomSampling3::kEntryName); EXPECT_EQ(1u, entries.size()); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kAverageViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kAverageViewportAdDensityName, 0); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kVarianceViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kVarianceViewportAdDensityName, 0); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kSkewnessViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kSkewnessViewportAdDensityName, 0); ukm_recorder.ExpectEntryMetric( entries.front(), - ukm::builders::AdPageLoadCustomSampling2::kKurtosisViewportAdDensityName, + ukm::builders::AdPageLoadCustomSampling3::kKurtosisViewportAdDensityName, -3); }
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.cc b/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.cc index f7ac4e7..2ae612b 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.cc +++ b/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.cc
@@ -14,6 +14,8 @@ namespace { +using RectId = PageAdDensityTracker::RectId; + int CalculateIntersectedLength(int start1, int end1, int start2, int end2) { DCHECK_LE(start1, end1); DCHECK_LE(start2, end2); @@ -34,7 +36,7 @@ // An event to process corresponding to the left or right point of each // line segment. struct SegmentEvent { - SegmentEvent(int segment_id, int pos, bool is_segment_start) + SegmentEvent(RectId segment_id, int pos, bool is_segment_start) : segment_id(segment_id), pos(pos), is_segment_start(is_segment_start) {} @@ -44,7 +46,7 @@ bool operator<(const SegmentEvent& rhs) const { if (pos == rhs.pos) { // We do not have 0-length segment. - DCHECK_NE(segment_id, rhs.segment_id); + DCHECK(segment_id != rhs.segment_id); return segment_id < rhs.segment_id; } else { @@ -52,7 +54,7 @@ } } - int segment_id; + RectId segment_id; int pos; bool is_segment_start; }; @@ -82,7 +84,7 @@ // Add a line segment to the set of active line segments, the segment // corresponds to the bottom or top of a rect. - void AddSegment(int segment_id, int start, int end) { + void AddSegment(RectId segment_id, int start, int end) { DCHECK_LE(start, end); int clipped_start = std::max(bound_start_, start); @@ -106,7 +108,7 @@ } // Remove a segment from the set of active line segmnets. - void RemoveSegment(int segment_id) { + void RemoveSegment(RectId segment_id) { auto it = segment_event_iterators_.find(segment_id); if (it == segment_event_iterators_.end()) return; @@ -154,12 +156,17 @@ std::set<SegmentEvent> active_segments_; // Map from the segment_id passed by user to the Segment struct. - std::unordered_map<int, SegmentEventSetIterators> segment_event_iterators_; + std::map<RectId, SegmentEventSetIterators> segment_event_iterators_; }; } // namespace -PageAdDensityTracker::RectEvent::RectEvent(int id, +PageAdDensityTracker::RectId::RectId(RectType rect_type, int id) + : rect_type(rect_type), id(id) {} + +PageAdDensityTracker::RectId::RectId(const RectId& other) = default; + +PageAdDensityTracker::RectEvent::RectEvent(RectId id, bool is_bottom, const gfx::Rect& rect) : rect_id(id), is_bottom(is_bottom), rect(rect) {} @@ -199,7 +206,9 @@ return last_viewport_ad_density_by_area_; } -void PageAdDensityTracker::AddRect(int rect_id, const gfx::Rect& rect) { +void PageAdDensityTracker::AddRect(RectId rect_id, + const gfx::Rect& rect, + bool recalculate_density) { // Check that we do not already have rect events for the rect. DCHECK(rect_events_iterators_.find(rect_id) == rect_events_iterators_.end()); @@ -220,15 +229,18 @@ rect_events_iterators_.emplace(rect_id, RectEventSetIterators(top_it, bottom_it)); - // TODO(https://crbug.com/1068586): Improve performance by adding additional - // throttling to only calculate when max density can decrease (frame deleted - // or moved). - CalculatePageAdDensity(); + if (recalculate_density) { + // TODO(https://crbug.com/1068586): Improve performance by adding additional + // throttling to only calculate when max density can decrease (frame deleted + // or moved). + CalculatePageAdDensity(); - CalculateViewportAdDensity(); + CalculateViewportAdDensity(); + } } -void PageAdDensityTracker::RemoveRect(int rect_id) { +void PageAdDensityTracker::RemoveRect(RectId rect_id, + bool recalculate_viewport_density) { auto it = rect_events_iterators_.find(rect_id); if (it == rect_events_iterators_.end()) @@ -238,6 +250,10 @@ rect_events_.erase(set_its.top_it); rect_events_.erase(set_its.bottom_it); rect_events_iterators_.erase(it); + + if (recalculate_viewport_density) { + CalculateViewportAdDensity(); + } } void PageAdDensityTracker::UpdateMainFrameRect(const gfx::Rect& rect) { @@ -256,6 +272,22 @@ CalculateViewportAdDensity(); } +void PageAdDensityTracker::UpdateMainFrameImageAdRects( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) { + for (auto const& [element_id, rect] : main_frame_image_ad_rects) { + RectId rect_id = RectId(RectType::kElement, element_id); + + RemoveRect(rect_id, /*recalculate_viewport_density=*/false); + + if (!rect.IsEmpty()) { + AddRect(rect_id, rect, /*recalculate_density=*/false); + } + } + + CalculatePageAdDensity(); + CalculateViewportAdDensity(); +} + void PageAdDensityTracker::Finalize() { DCHECK(!finalize_called_); @@ -410,6 +442,22 @@ return result; } +bool PageAdDensityTracker::RectId::operator<(const RectId& rhs) const { + if (rect_type == rhs.rect_type) { + return id < rhs.id; + } + + return rect_type < rhs.rect_type; +} + +bool PageAdDensityTracker::RectId::operator==(const RectId& rhs) const { + return rect_type == rhs.rect_type && id == rhs.id; +} + +bool PageAdDensityTracker::RectId::operator!=(const RectId& rhs) const { + return !(*this == rhs); +} + bool PageAdDensityTracker::RectEvent::operator<(const RectEvent& rhs) const { int lhs_y = is_bottom ? rect.bottom() : rect.y(); int rhs_y = rhs.is_bottom ? rhs.rect.bottom() : rhs.rect.y(); @@ -417,7 +465,7 @@ // Tiebreak with |rect_id|. if (lhs_y == rhs_y) { // We do not have 0-length Rect. - DCHECK_NE(rect_id, rhs.rect_id); + DCHECK(rect_id != rhs.rect_id); return rect_id < rhs.rect_id; } else { return lhs_y > rhs_y;
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.h b/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.h index d32e67a..945efd05 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.h +++ b/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker.h
@@ -5,9 +5,10 @@ #ifndef COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_ #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_ +#include <map> #include <set> -#include <unordered_map> +#include <base/containers/flat_map.h> #include "base/memory/raw_ptr.h" #include "base/time/tick_clock.h" #include "base/time/time.h" @@ -28,6 +29,24 @@ // current viewport ad density using CalculateViewportAdDensity. class PageAdDensityTracker { public: + enum class RectType { kIFrame, kElement }; + + struct RectId { + RectId(RectType rect_type, int id); + RectId(const RectId& other); + + RectType rect_type; + + // For iframe, the id comes from the frame tree node id. For other elements + // (e.g. main frame ad rectangles), the id comes from the node id from the + // renderer. + int id; + + bool operator<(const RectId& rhs) const; + bool operator==(const RectId& rhs) const; + bool operator!=(const RectId& rhs) const; + }; + struct AdDensityCalculationResult { absl::optional<int> ad_density_by_height; absl::optional<int> ad_density_by_area; @@ -39,12 +58,15 @@ PageAdDensityTracker(const PageAdDensityTracker&) = delete; PageAdDensityTracker& operator=(const PageAdDensityTracker&) = delete; - // Operations to track sub frame rects in the page density calcluation. - void AddRect(int rect_id, const gfx::Rect& rect); + // Operations to track sub frame rects in the page density calcluation. If + // `recalculate_density` is true, the max page ad density and the viewport ad + // density will be recalculated in the end. + void AddRect(RectId rect_id, const gfx::Rect& rect, bool recalculate_density); // Removes a rect from the tracker if it is currently being tracked. - // Otherwise RemoveRect is a no op. - void RemoveRect(int rect_id); + // Otherwise RemoveRect is a no op. If `recalculate_viewport_density` is true, + // the viewport ad density will be recalculated in the end. + void RemoveRect(RectId rect_id, bool recalculate_viewport_density); // Operations to track the main frame dimensions. The main frame rect has to // be set to calculate the page ad density. @@ -54,6 +76,10 @@ // rect has to be set to calculate the viewport ad density. void UpdateMainFrameViewportRect(const gfx::Rect& rect); + // Operations to track the main frame ad rectangles' position and dimensions. + void UpdateMainFrameImageAdRects( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects); + // Returns the density by height, as a value from 0-100. If the density // calculation fails (i.e. no main frame size), this returns -1. Percentage // density by height is calculated as the the combined height of ads divided @@ -83,12 +109,12 @@ private: // An event to process corresponding to the top or bottom of each rect. struct RectEvent { - RectEvent(int id, bool is_bottom, const gfx::Rect& rect); + RectEvent(RectId id, bool is_bottom, const gfx::Rect& rect); RectEvent(const RectEvent& other); // A unique identifier set when adding and removing rect events // corresponding to a single rect. - int rect_id; + RectId rect_id; bool is_bottom; gfx::Rect rect; @@ -127,7 +153,7 @@ // Map from rect_id to iterators of rect events in rect_events_. This allows // efficient removal according to rect_id. - std::unordered_map<int, RectEventSetIterators> rect_events_iterators_; + std::map<RectId, RectEventSetIterators> rect_events_iterators_; // Percentage of page ad density as a value from 0-100. These only have // a value of -1 when ad density has not yet been calculated successfully.
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker_unittest.cc b/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker_unittest.cc index 7e73072..4376d35 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker_unittest.cc +++ b/components/page_load_metrics/browser/observers/ad_metrics/page_ad_density_tracker_unittest.cc
@@ -11,12 +11,23 @@ namespace page_load_metrics { +namespace { + +using RectId = PageAdDensityTracker::RectId; +using RectType = PageAdDensityTracker::RectType; + +const RectId kRectId1 = RectId(RectType::kIFrame, 1); +const RectId kRectId2 = RectId(RectType::kElement, 1); +const RectId kRectId3 = RectId(RectType::kElement, 2); + +} // namespace + // Only for test purpose. class PageAdDensityTrackerTestPeer { public: static bool RectExistsAndHasCorrectTopIterator( const PageAdDensityTracker& tracker, - int rect_id) { + RectId rect_id) { auto it = tracker.rect_events_iterators_.find(rect_id); // Rect not exists. if (it == tracker.rect_events_iterators_.end()) @@ -27,7 +38,7 @@ static bool RectExistsAndHasCorrectBottomIterator( const PageAdDensityTracker& tracker, - int rect_id) { + RectId rect_id) { auto it = tracker.rect_events_iterators_.find(rect_id); // Rect not exists. if (it == tracker.rect_events_iterators_.end()) @@ -44,20 +55,23 @@ EXPECT_EQ(tracker.MaxPageAdDensityByArea(), -1); tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 100, 10), + /*recalculate_density=*/true); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 10); - tracker.AddRect(2 /* rect_id */, gfx::Rect(50, 0, 100, 20)); + tracker.AddRect(kRectId2, gfx::Rect(50, 0, 100, 20), + /*recalculate_density=*/true); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 15); EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 20); - tracker.AddRect(3 /* rect_id */, gfx::Rect(50, 50, 50, 50)); + tracker.AddRect(kRectId3, gfx::Rect(50, 50, 50, 50), + /*recalculate_density=*/true); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 40); EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 70); // Removing a rect should not change the maximum ad density. - tracker.RemoveRect(3 /* rect_id */); + tracker.RemoveRect(kRectId3, /*recalculate_viewport_density=*/false); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 40); EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 70); } @@ -67,9 +81,10 @@ TEST(PageAdDensityTrackerTest, RemoveRectTwice_SecondRemoveIgnored) { PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - tracker.RemoveRect(1 /* rect_id */); - tracker.RemoveRect(1 /* rect_id */); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 100, 10), + /*recalculate_density=*/true); + tracker.RemoveRect(kRectId1, /*recalculate_viewport_density=*/false); + tracker.RemoveRect(kRectId1, /*recalculate_viewport_density=*/false); } // Ensures that two rects with the same dimensions hash to different @@ -79,12 +94,14 @@ tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - tracker.AddRect(2 /* rect_id */, gfx::Rect(0, 0, 100, 10)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 100, 10), + /*recalculate_density=*/true); + tracker.AddRect(kRectId2, gfx::Rect(0, 0, 100, 10), + /*recalculate_density=*/true); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); - tracker.RemoveRect(1 /* rect_id */); - tracker.RemoveRect(2 /* rect_id */); + tracker.RemoveRect(kRectId1, /*recalculate_viewport_density=*/false); + tracker.RemoveRect(kRectId2, /*recalculate_viewport_density=*/false); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); } @@ -92,13 +109,17 @@ TEST(PageAdDensityTrackerTest, TwoRectsOverflowTotalAreaAndHeight) { PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, gfx::Rect(std::numeric_limits<int>::min(), 0, - std::numeric_limits<int>::max(), - std::numeric_limits<int>::max())); - tracker.AddRect(2 /* rect_id */, gfx::Rect(std::numeric_limits<int>::min(), - std::numeric_limits<int>::max(), - std::numeric_limits<int>::max(), - std::numeric_limits<int>::max())); + tracker.AddRect(kRectId1, + gfx::Rect(std::numeric_limits<int>::min(), 0, + std::numeric_limits<int>::max(), + std::numeric_limits<int>::max()), + /*recalculate_density=*/true); + tracker.AddRect(kRectId2, + gfx::Rect(std::numeric_limits<int>::min(), + std::numeric_limits<int>::max(), + std::numeric_limits<int>::max(), + std::numeric_limits<int>::max()), + /*recalculate_density=*/true); // Update main frame rect to force a calculation. tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); @@ -112,9 +133,10 @@ TEST(PageAdDensityTrackerTest, OverflowTotalAreaAndHeight) { PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, + tracker.AddRect(kRectId1, gfx::Rect(0, 0, std::numeric_limits<int>::max(), - std::numeric_limits<int>::max())); + std::numeric_limits<int>::max()), + /*recalculate_density=*/true); // Update main frame rect to force a calculation. tracker.UpdateMainFrameRect(gfx::Rect(0, 0, std::numeric_limits<int>::max(), @@ -132,7 +154,8 @@ tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(-1, -1, 1, 1)); + tracker.AddRect(kRectId1, gfx::Rect(-1, -1, 1, 1), + /*recalculate_density=*/true); EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 0); EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 0); @@ -142,9 +165,10 @@ TEST(PageAdDensityTrackerTest, ViewportAdDensity_OverflowViewportArea) { PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, + tracker.AddRect(kRectId1, gfx::Rect(0, 0, std::numeric_limits<int>::max(), - std::numeric_limits<int>::max())); + std::numeric_limits<int>::max()), + /*recalculate_density=*/true); tracker.UpdateMainFrameViewportRect(gfx::Rect( 0, 0, std::numeric_limits<int>::max(), std::numeric_limits<int>::max())); @@ -157,7 +181,8 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 100)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 100, 100), + /*recalculate_density=*/true); EXPECT_EQ(tracker.ViewportAdDensityByArea(), 100); } @@ -166,7 +191,8 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 100)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 100), + /*recalculate_density=*/true); EXPECT_EQ(tracker.ViewportAdDensityByArea(), 50); } @@ -175,7 +201,8 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(100, 0, 100, 100)); + tracker.AddRect(kRectId1, gfx::Rect(100, 0, 100, 100), + /*recalculate_density=*/true); EXPECT_EQ(tracker.ViewportAdDensityByArea(), 0); } @@ -184,7 +211,8 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(50, 50, 100, 100)); + tracker.AddRect(kRectId1, gfx::Rect(50, 50, 100, 100), + /*recalculate_density=*/true); EXPECT_EQ(tracker.ViewportAdDensityByArea(), 25); } @@ -193,8 +221,10 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(30, 70, 100, 100)); - tracker.AddRect(2 /* rect_id */, gfx::Rect(70, 30, 100, 100)); + tracker.AddRect(kRectId1, gfx::Rect(30, 70, 100, 100), + /*recalculate_density=*/true); + tracker.AddRect(kRectId2, gfx::Rect(70, 30, 100, 100), + /*recalculate_density=*/true); EXPECT_EQ(tracker.ViewportAdDensityByArea(), 33); // ((30 * 70 * 2) - 30 * 30) / 10000 * 100 @@ -207,7 +237,8 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); tracker.Finalize(); EXPECT_DOUBLE_EQ(tracker.GetAdDensityByAreaStats().mean, 0); @@ -218,7 +249,8 @@ base::test::TaskEnvironment::TimeSource::MOCK_TIME); PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); task_environment.FastForwardBy(base::Seconds(1)); tracker.Finalize(); @@ -246,7 +278,8 @@ task_environment.FastForwardBy(base::Seconds(1)); tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 50)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); EXPECT_EQ(tracker.ViewportAdDensityByArea(), 100); @@ -263,7 +296,8 @@ task_environment.FastForwardBy(base::Seconds(1)); tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 50)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); task_environment.FastForwardBy(base::Seconds(1)); @@ -280,7 +314,8 @@ PageAdDensityTracker tracker; tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); task_environment.FastForwardBy(base::Seconds(1)); @@ -297,7 +332,8 @@ base::test::TaskEnvironment::TimeSource::MOCK_TIME); PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 50)); task_environment.FastForwardBy(base::Seconds(1)); @@ -314,13 +350,15 @@ base::test::TaskEnvironment::TimeSource::MOCK_TIME); PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 100)); task_environment.FastForwardBy(base::Seconds(1)); - tracker.RemoveRect(1 /* rect_id */); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 100)); + tracker.RemoveRect(kRectId1, /*recalculate_viewport_density=*/false); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 100), + /*recalculate_density=*/true); task_environment.FastForwardBy(base::Seconds(1)); tracker.Finalize(); @@ -328,12 +366,103 @@ } TEST(PageAdDensityTrackerTest, + AverageViewportAdDensity_RectRemovedAndRecalculateDensity) { + base::test::SingleThreadTaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + PageAdDensityTracker tracker; + + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); + tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 100)); + + task_environment.FastForwardBy(base::Seconds(1)); + + tracker.RemoveRect(kRectId1, /*recalculate_viewport_density=*/true); + + task_environment.FastForwardBy(base::Seconds(1)); + tracker.Finalize(); + + EXPECT_DOUBLE_EQ(tracker.GetAdDensityByAreaStats().mean, 25); +} + +TEST(PageAdDensityTrackerTest, AverageViewportAdDensity_ImageAdRects_Simple) { + base::test::SingleThreadTaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + PageAdDensityTracker tracker; + + tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); + + base::flat_map<int, gfx::Rect> rects; + rects.emplace(1, gfx::Rect(0, 0, 50, 50)); + rects.emplace(2, gfx::Rect(0, 50, 100, 50)); + + tracker.UpdateMainFrameImageAdRects(rects); + + task_environment.FastForwardBy(base::Seconds(1)); + tracker.Finalize(); + + EXPECT_DOUBLE_EQ(tracker.GetAdDensityByAreaStats().mean, 75); +} + +TEST(PageAdDensityTrackerTest, AverageViewportAdDensity_ImageAdRects_Removal) { + base::test::SingleThreadTaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + PageAdDensityTracker tracker; + + tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); + + { + base::flat_map<int, gfx::Rect> rects; + rects.emplace(1, gfx::Rect(0, 0, 50, 50)); + rects.emplace(2, gfx::Rect(0, 50, 100, 50)); + + tracker.UpdateMainFrameImageAdRects(rects); + } + task_environment.FastForwardBy(base::Seconds(1)); + + { + base::flat_map<int, gfx::Rect> rects; + rects.emplace(2, gfx::Rect()); + + tracker.UpdateMainFrameImageAdRects(rects); + } + task_environment.FastForwardBy(base::Seconds(1)); + + tracker.Finalize(); + + EXPECT_DOUBLE_EQ(tracker.GetAdDensityByAreaStats().mean, 50); +} + +TEST(PageAdDensityTrackerTest, + AverageViewportAdDensity_ImageAdRects_MixedWithIframeRects) { + base::test::SingleThreadTaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + PageAdDensityTracker tracker; + + tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 100, 100)); + + tracker.AddRect(RectId(RectType::kIFrame, /*id=*/1), gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); + base::flat_map<int, gfx::Rect> rects; + rects.emplace(1, gfx::Rect(0, 50, 100, 50)); + + tracker.UpdateMainFrameImageAdRects(rects); + + task_environment.FastForwardBy(base::Seconds(1)); + + tracker.Finalize(); + + EXPECT_DOUBLE_EQ(tracker.GetAdDensityByAreaStats().mean, 75); +} + +TEST(PageAdDensityTrackerTest, AverageViewportAdDensity_MultipleUnequalTimePeriods) { base::test::SingleThreadTaskEnvironment task_environment( base::test::TaskEnvironment::TimeSource::MOCK_TIME); PageAdDensityTracker tracker; - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); tracker.UpdateMainFrameViewportRect(gfx::Rect(0, 0, 50, 100)); task_environment.FastForwardBy(base::Seconds(1)); @@ -359,14 +488,17 @@ tracker.UpdateMainFrameViewportRect(gfx::Rect(50, 0, 50, 100)); // Rect(1) is not within the viewport. - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 50, 50)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 50), + /*recalculate_density=*/true); // Rect(2) occupy 1/4 of the viewport. - tracker.AddRect(2 /* rect_id */, gfx::Rect(25, 0, 50, 50)); + tracker.AddRect(kRectId2, gfx::Rect(25, 0, 50, 50), + /*recalculate_density=*/true); // Rect(3) occupy 1/4 of the viewport; 1/8 of the viewport is occupied by both // Rect(2) and Rect(3) - tracker.AddRect(3 /* rect_id */, gfx::Rect(25, 25, 50, 50)); + tracker.AddRect(kRectId3, gfx::Rect(25, 25, 50, 50), + /*recalculate_density=*/true); task_environment.FastForwardBy(base::Seconds(1)); tracker.Finalize(); @@ -375,15 +507,15 @@ TEST(PageAdDensityTrackerTest, RectEvent_CheckTopAndBottomIterator) { PageAdDensityTracker tracker; - int rect_id = 1; - tracker.AddRect(rect_id, gfx::Rect(0, 0, 50, 10)); + tracker.AddRect(kRectId1, gfx::Rect(0, 0, 50, 10), + /*recalculate_density=*/true); EXPECT_TRUE(PageAdDensityTrackerTestPeer::RectExistsAndHasCorrectTopIterator( - tracker, rect_id)); + tracker, kRectId1)); EXPECT_TRUE( PageAdDensityTrackerTestPeer::RectExistsAndHasCorrectBottomIterator( - tracker, rect_id)); - tracker.RemoveRect(rect_id); + tracker, kRectId1)); + tracker.RemoveRect(kRectId1, /*recalculate_viewport_density=*/true); } } // namespace page_load_metrics
diff --git a/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.h b/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.h index f019932..f040619 100644 --- a/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.h +++ b/components/page_load_metrics/browser/observers/assert_page_load_metrics_observer.h
@@ -170,6 +170,8 @@ const gfx::Rect& main_frame_intersection_rect) override {} void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) override {} + void OnMainFrameImageAdRectsChanged(const base::flat_map<int, gfx::Rect>& + main_frame_image_ad_rects) override {} void OnLoadedResource(const page_load_metrics::ExtraRequestCompleteInfo& extra_request_complete_info) override {} void FrameReceivedUserActivation(
diff --git a/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc b/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc index 341a47b..fd715f8 100644 --- a/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc +++ b/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc
@@ -281,6 +281,14 @@ parent_observer_->OnMainFrameViewportRectChanged(main_frame_viewport_rect); } +void PageLoadMetricsForwardObserver::OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) { + if (!parent_observer_) { + return; + } + parent_observer_->OnMainFrameImageAdRectsChanged(main_frame_image_ad_rects); +} + // Don't need to forward FlushMetricsOnAppEnterBackground and OnComplete as they // are dispatched to all trackers. PageLoadMetricsObserverInterface::ObservePolicy
diff --git a/components/page_load_metrics/browser/page_load_metrics_forward_observer.h b/components/page_load_metrics/browser/page_load_metrics_forward_observer.h index 36b45cf..b330026 100644 --- a/components/page_load_metrics/browser/page_load_metrics_forward_observer.h +++ b/components/page_load_metrics/browser/page_load_metrics_forward_observer.h
@@ -121,6 +121,8 @@ const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) override; ObservePolicy FlushMetricsOnAppEnterBackground( const mojom::PageLoadTiming& timing) override; void OnComplete(const mojom::PageLoadTiming& timing) override;
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer.h b/components/page_load_metrics/browser/page_load_metrics_observer.h index 4e6925c1..595be88 100644 --- a/components/page_load_metrics/browser/page_load_metrics_observer.h +++ b/components/page_load_metrics/browser/page_load_metrics_observer.h
@@ -200,6 +200,8 @@ const gfx::Rect& main_frame_intersection_rect) override {} void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) override {} + void OnMainFrameImageAdRectsChanged(const base::flat_map<int, gfx::Rect>& + main_frame_image_ad_rects) override {} ObservePolicy FlushMetricsOnAppEnterBackground( const mojom::PageLoadTiming& timing) override; void OnComplete(const mojom::PageLoadTiming& timing) override {}
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer_interface.h b/components/page_load_metrics/browser/page_load_metrics_observer_interface.h index ecebf43..b7532a3 100644 --- a/components/page_load_metrics/browser/page_load_metrics_observer_interface.h +++ b/components/page_load_metrics/browser/page_load_metrics_observer_interface.h
@@ -462,6 +462,11 @@ virtual void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) = 0; + // Called when an image ad rectangle changed. An empty `image_ad_rect` is used + // to signal the removal of the rectangle. Only invoked on the main frame. + virtual void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) = 0; + // Invoked when the UMA metrics subsystem is persisting metrics as the // application goes into the background, on platforms where the browser // process may be killed after backgrounding (Android). Implementers should
diff --git a/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc b/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc index 7fc1b31..7dd3935 100644 --- a/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc +++ b/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc
@@ -82,6 +82,8 @@ const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) override; void OnV8MemoryChanged( const std::vector<MemoryUpdate>& memory_updates) override; void OnPageRenderDataUpdate(const mojom::FrameRenderDataUpdate& render_data, @@ -181,6 +183,10 @@ expected_.did_set_main_frame_intersection_ = true; } +void PageLoadMetricsTestWaiter::SetMainFrameImageAdRectsExpectation() { + expected_.did_observed_main_frame_image_ad_rects_ = true; +} + void PageLoadMetricsTestWaiter::AddMainFrameViewportRectExpectation( const gfx::Rect& rect) { expected_.main_frame_viewport_rect_ = rect; @@ -255,6 +261,17 @@ static_cast<blink::UseCounterFeature::EnumValue>(feature)}); } +bool PageLoadMetricsTestWaiter::DidObserveMainFrameImageAdRect( + const gfx::Rect& rect) const { + for (auto& [id, observed_rect] : main_frame_image_ad_rects_) { + if (observed_rect == rect) { + return true; + } + } + + return false; +} + void PageLoadMetricsTestWaiter::Wait() { if (!ExpectationsSatisfied()) { run_loop_ = std::make_unique<base::RunLoop>(); @@ -389,6 +406,23 @@ run_loop_->Quit(); } +void PageLoadMetricsTestWaiter::OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) { + if (main_frame_image_ad_rects.empty()) { + return; + } + + observed_.did_observed_main_frame_image_ad_rects_ = true; + + for (auto& [id, rect] : main_frame_image_ad_rects) { + main_frame_image_ad_rects_[id] = rect; + } + + if (ExpectationsSatisfied() && run_loop_) { + run_loop_->Quit(); + } +} + void PageLoadMetricsTestWaiter::OnDidFinishSubFrameNavigation( content::NavigationHandle* navigation_handle) { observed_.subframe_navigation_ = true; @@ -605,6 +639,15 @@ expected_.main_frame_viewport_rect_; } +bool PageLoadMetricsTestWaiter::MainFrameImageAdRectsExpectationsSatisfied() + const { + if (!expected_.did_observed_main_frame_image_ad_rects_) { + return true; + } + + return observed_.did_observed_main_frame_image_ad_rects_; +} + bool PageLoadMetricsTestWaiter::MemoryUpdateExpectationsSatisfied() const { return IsSubset(expected_.memory_update_frame_ids_, observed_.memory_update_frame_ids_); @@ -638,6 +681,7 @@ CpuTimeExpectationsSatisfied() && MainFrameIntersectionExpectationsSatisfied() && MainFrameViewportRectExpectationsSatisfied() && + MainFrameImageAdRectsExpectationsSatisfied() && MemoryUpdateExpectationsSatisfied() && TotalInputDelayExpectationsSatisfied() && LayoutShiftExpectationsSatisfied() && @@ -758,6 +802,13 @@ } } +void WaiterMetricsObserver::OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) { + if (waiter_) { + waiter_->OnMainFrameImageAdRectsChanged(main_frame_image_ad_rects); + } +} + void WaiterMetricsObserver::OnDidFinishSubFrameNavigation( content::NavigationHandle* navigation_handle) { if (waiter_)
diff --git a/components/page_load_metrics/browser/page_load_metrics_test_waiter.h b/components/page_load_metrics/browser/page_load_metrics_test_waiter.h index 458daac..a1d37419 100644 --- a/components/page_load_metrics/browser/page_load_metrics_test_waiter.h +++ b/components/page_load_metrics/browser/page_load_metrics_test_waiter.h
@@ -81,6 +81,10 @@ // TODO(skobes): Unify this API with AddMainFrameIntersectionExpectation. void SetMainFrameIntersectionExpectation(); + // Indicates that we expect at least one notification for the + // main frame image ad rectangles update, with any rect allowed. + void SetMainFrameImageAdRectsExpectation(); + // Add a main frame viewport intersection expectation. Expects that the // mainframe receives its viewport rectangle in the main frame document's // coornidate. Subsequent calls overwrite unmet expectations. @@ -126,6 +130,9 @@ // Whether the given WebFeature was observed in the page. bool DidObserveWebFeature(blink::mojom::WebFeature feature) const; + // Whether the given image ad rect was observed in the page. + bool DidObserveMainFrameImageAdRect(const gfx::Rect& rect) const; + // Waits for PageLoadMetrics events that match the fields set by the add // expectation methods. All matching fields must be set to end this wait. // All expectations are reset when the wait ends. @@ -276,6 +283,9 @@ void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect); + void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects); + void OnDidFinishSubFrameNavigation( content::NavigationHandle* navigation_handle); @@ -298,6 +308,7 @@ bool SubframeDataExpectationsSatisfied() const; bool MainFrameIntersectionExpectationsSatisfied() const; bool MainFrameViewportRectExpectationsSatisfied() const; + bool MainFrameImageAdRectsExpectationsSatisfied() const; bool MemoryUpdateExpectationsSatisfied() const; bool TotalInputDelayExpectationsSatisfied() const; bool LayoutShiftExpectationsSatisfied() const; @@ -321,6 +332,7 @@ bool subframe_data_ = false; std::set<gfx::Size, FrameSizeComparator> frame_sizes_; bool did_set_main_frame_intersection_ = false; + bool did_observed_main_frame_image_ad_rects_ = false; std::vector<gfx::Rect> main_frame_intersections_; absl::optional<gfx::Rect> main_frame_viewport_rect_; std::unordered_set<content::GlobalRenderFrameHostId, @@ -334,6 +346,10 @@ int current_complete_resources_ = 0; int64_t current_network_bytes_ = 0; + // The last observed main frame image ad rectangle for each image id. This + // doesn't get reset in `ResetExpectations`. + base::flat_map<int, gfx::Rect> main_frame_image_ad_rects_; + // Network body bytes are only counted for complete resources. int64_t current_network_body_bytes_ = 0; int expected_minimum_complete_resources_ = 0;
diff --git a/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.cc b/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.cc index 29a59fb..312b902 100644 --- a/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.cc +++ b/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.cc
@@ -752,6 +752,9 @@ MaybeUpdateMainFrameIntersectionRect(render_frame_host, main_frame_metadata_); MaybeUpdateMainFrameViewportRect(main_frame_metadata_); + + client_->OnMainFrameImageAdRectsChanged( + main_frame_metadata_->main_frame_image_ad_rects); } }
diff --git a/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.h b/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.h index a2ef17d6..507c9fa5 100644 --- a/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.h +++ b/components/page_load_metrics/browser/page_load_metrics_update_dispatcher.h
@@ -149,6 +149,8 @@ const gfx::Rect& main_frame_intersection_rect) = 0; virtual void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) = 0; + virtual void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) = 0; virtual void SetUpSharedMemoryForSmoothness( base::ReadOnlySharedMemoryRegion shared_memory) = 0; };
diff --git a/components/page_load_metrics/browser/page_load_tracker.cc b/components/page_load_metrics/browser/page_load_tracker.cc index dda95f9..4243062 100644 --- a/components/page_load_metrics/browser/page_load_tracker.cc +++ b/components/page_load_metrics/browser/page_load_tracker.cc
@@ -984,6 +984,13 @@ } } +void PageLoadTracker::OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) { + for (const auto& observer : observers_) { + observer->OnMainFrameImageAdRectsChanged(main_frame_image_ad_rects); + } +} + content::WebContents* PageLoadTracker::GetWebContents() const { return web_contents_; }
diff --git a/components/page_load_metrics/browser/page_load_tracker.h b/components/page_load_metrics/browser/page_load_tracker.h index 65528a5..79ecae83 100644 --- a/components/page_load_metrics/browser/page_load_tracker.h +++ b/components/page_load_metrics/browser/page_load_tracker.h
@@ -231,6 +231,8 @@ const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectsChanged( + const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) override; void SetUpSharedMemoryForSmoothness( base::ReadOnlySharedMemoryRegion shared_memory) override;
diff --git a/components/page_load_metrics/common/page_load_metrics.mojom b/components/page_load_metrics/common/page_load_metrics.mojom index 92ee6c0..8dbfa57 100644 --- a/components/page_load_metrics/common/page_load_metrics.mojom +++ b/components/page_load_metrics/common/page_load_metrics.mojom
@@ -212,6 +212,12 @@ // computed, and for any subsequent changes, and is null otherwise (i.e. // hasn't changed). gfx.mojom.Rect? main_frame_viewport_rect; + + // The image ad rectangles within the main frame. Empty rectangles are used to + // signal the removal of the rectangle. The map keys are the element ids. This + // is only populated for the main frame, for the first time + // each rectangle is initially computed and for any subsequent changes. + map<int32, gfx.mojom.Rect> main_frame_image_ad_rects; }; struct SubresourceLoadMetrics {
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc index 5078d57b..3cfd00c 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
@@ -388,6 +388,15 @@ } } +void MetricsRenderFrameObserver::OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) { + if (page_timing_metrics_sender_) { + page_timing_metrics_sender_->OnMainFrameImageAdRectangleChanged( + element_id, image_ad_rect); + } +} + void MetricsRenderFrameObserver::OnFrameDetached() { WillDetach(); }
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.h b/components/page_load_metrics/renderer/metrics_render_frame_observer.h index 4f73dd4..1997b2b8 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer.h +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.h
@@ -107,6 +107,9 @@ const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) override; // blink::WebLocalFrameObserver implementation void OnFrameDetached() override;
diff --git a/components/page_load_metrics/renderer/page_timing_metrics_sender.cc b/components/page_load_metrics/renderer/page_timing_metrics_sender.cc index c5e680c..6f7ef33d 100644 --- a/components/page_load_metrics/renderer/page_timing_metrics_sender.cc +++ b/components/page_load_metrics/renderer/page_timing_metrics_sender.cc
@@ -226,6 +226,13 @@ EnsureSendTimer(); } +void PageTimingMetricsSender::OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) { + metadata_->main_frame_image_ad_rects[element_id] = image_ad_rect; + EnsureSendTimer(); +} + void PageTimingMetricsSender::UpdateResourceMetadata( int resource_id, bool reported_as_ad_resource, @@ -336,6 +343,7 @@ new_features_.clear(); metadata_->main_frame_intersection_rect.reset(); metadata_->main_frame_viewport_rect.reset(); + metadata_->main_frame_image_ad_rects.clear(); last_cpu_timing_->task_time = base::TimeDelta(); modified_resources_.clear(); render_data_.new_layout_shifts.clear();
diff --git a/components/page_load_metrics/renderer/page_timing_metrics_sender.h b/components/page_load_metrics/renderer/page_timing_metrics_sender.h index 5c60099..289e7a6 100644 --- a/components/page_load_metrics/renderer/page_timing_metrics_sender.h +++ b/components/page_load_metrics/renderer/page_timing_metrics_sender.h
@@ -73,6 +73,8 @@ const gfx::Rect& main_frame_intersection_rect); void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect); + void OnMainFrameImageAdRectangleChanged(int element_id, + const gfx::Rect& image_ad_rect); void DidObserveInputDelay(base::TimeDelta input_delay); void DidObserveUserInteraction(base::TimeDelta max_event_duration,
diff --git a/components/segmentation_platform/internal/execution/model_executor_impl.cc b/components/segmentation_platform/internal/execution/model_executor_impl.cc index f341f91..5c93907 100644 --- a/components/segmentation_platform/internal/execution/model_executor_impl.cc +++ b/components/segmentation_platform/internal/execution/model_executor_impl.cc
@@ -186,7 +186,7 @@ clock_->Now() - state->model_execution_start_time); // TODO(ritikagup): Change the use of this according to MultiOutputModel. if (result.has_value()) { - VLOG(0) << "Segmentation model result: " << result.value().at(0) + VLOG(1) << "Segmentation model result: " << result.value().at(0) << " for segment " << proto::SegmentId_Name(state->segment_info.segment_id()); const proto::SegmentationModelMetadata& model_metadata =
diff --git a/components/services/storage/shared_storage/async_shared_storage_database_impl_unittest.cc b/components/services/storage/shared_storage/async_shared_storage_database_impl_unittest.cc index 2bc8a07..c4ec814 100644 --- a/components/services/storage/shared_storage/async_shared_storage_database_impl_unittest.cc +++ b/components/services/storage/shared_storage/async_shared_storage_database_impl_unittest.cc
@@ -2025,12 +2025,10 @@ origins.push_back(info->storage_key.origin()); EXPECT_THAT(origins, ElementsAre(kOrigin2, kOrigin4)); - // `kOrigin1` is still in `per_origin_mapping` even though it has no entries, - // as we didn't override its creation time to be old enough to have expired. origins.clear(); for (const auto& info : infos6) origins.push_back(info->storage_key.origin()); - EXPECT_THAT(origins, ElementsAre(kOrigin1, kOrigin2, kOrigin4)); + EXPECT_THAT(origins, ElementsAre(kOrigin2, kOrigin4)); // Database is still intact after trimming memory. EXPECT_EQ(OperationResult::kSuccess, result14);
diff --git a/components/services/storage/shared_storage/shared_storage_database.cc b/components/services/storage/shared_storage/shared_storage_database.cc index 8b0f0211..5a88449 100644 --- a/components/services/storage/shared_storage/shared_storage_database.cc +++ b/components/services/storage/shared_storage/shared_storage_database.cc
@@ -766,57 +766,43 @@ if (!transaction.Begin()) return OperationResult::kSqlError; + static constexpr char kUpdateLengthsSql[] = + "UPDATE per_origin_mapping SET length = length - counts.num_expired " + "FROM " + " (SELECT context_origin, COUNT(context_origin) AS num_expired " + " FROM values_mapping WHERE last_used_time<? " + " GROUP BY context_origin) " + "AS counts " + "WHERE per_origin_mapping.context_origin = counts.context_origin"; + + sql::Statement update_statement( + db_.GetCachedStatement(SQL_FROM_HERE, kUpdateLengthsSql)); + base::Time cutoff_time = clock_->Now() - staleness_threshold_; + update_statement.BindTime(0, cutoff_time); + + if (!update_statement.Run()) { + return OperationResult::kSqlError; + } + static constexpr char kDeleteEntriesSql[] = "DELETE FROM values_mapping WHERE last_used_time<?"; sql::Statement entries_statement( db_.GetCachedStatement(SQL_FROM_HERE, kDeleteEntriesSql)); - entries_statement.BindTime(0, clock_->Now() - staleness_threshold_); + entries_statement.BindTime(0, cutoff_time); // Delete expired entries. if (!entries_statement.Run()) return OperationResult::kSqlError; - static constexpr char kSelectSql[] = - "SELECT context_origin,creation_time,length FROM per_origin_mapping " - "ORDER BY creation_time"; - sql::Statement select_statement( - db_.GetCachedStatement(SQL_FROM_HERE, kSelectSql)); + static constexpr char kDeleteOriginsSql[] = + "DELETE FROM per_origin_mapping WHERE length<=0"; + sql::Statement origins_statement( + db_.GetCachedStatement(SQL_FROM_HERE, kDeleteOriginsSql)); - // Update `per_origin_mapping` to agree with the correct post-purge `length`s. - // Also, for any origins that are now empty and whose `creation_time`s are - // prior to the lookback window, remove them from `per_origin_mapping` - // entirely. - while (select_statement.Step()) { - std::string origin = select_statement.ColumnString(0); - base::Time creation_time = select_statement.ColumnTime(1); - int64_t reported_length = select_statement.ColumnInt64(2); - - // We want the count of all entries for this origin. There are unlikely to - // be any expired ones, since we just purged them, but one or more - // additional unpurged entries could have become expired in the meantime. - int64_t actual_length = - NumEntriesManualCount(origin, /*include_expired=*/true); - - if (actual_length == -1) - return OperationResult::kSqlError; - - if (actual_length == 0 && - creation_time < clock_->Now() - staleness_threshold_) { - if (!DeleteFromPerOriginMapping(origin)) - return OperationResult::kSqlError; - continue; - } - - if (actual_length == reported_length) { - continue; - } - - if (!UpdateLength(origin, actual_length - reported_length)) - return OperationResult::kSqlError; - } - - if (!select_statement.Succeeded()) + // Delete empty origins. + if (!origins_statement.Run()) { return OperationResult::kSqlError; + } static constexpr char kDeleteWithdrawalsSql[] = "DELETE FROM budget_mapping WHERE time_stamp<?"; @@ -1416,19 +1402,14 @@ } int64_t SharedStorageDatabase::NumEntriesManualCount( - const std::string& context_origin, - bool include_expired) { - const char* kCountSql = - (include_expired) - ? "SELECT COUNT(*) FROM values_mapping WHERE context_origin=?" - : "SELECT COUNT(*) FROM values_mapping " - "WHERE context_origin=? AND last_used_time>=?"; + const std::string& context_origin) { + static constexpr char kCountSql[] = + "SELECT COUNT(*) FROM values_mapping " + "WHERE context_origin=? AND last_used_time>=?"; - sql::Statement statement(db_.GetUniqueStatement(kCountSql)); + sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, kCountSql)); statement.BindString(0, context_origin); - - if (!include_expired) - statement.BindTime(1, clock_->Now() - staleness_threshold_); + statement.BindTime(1, clock_->Now() - staleness_threshold_); int64_t length = 0; if (statement.Step())
diff --git a/components/services/storage/shared_storage/shared_storage_database.h b/components/services/storage/shared_storage/shared_storage_database.h index cce3ae0b..f361b19 100644 --- a/components/services/storage/shared_storage/shared_storage_database.h +++ b/components/services/storage/shared_storage/shared_storage_database.h
@@ -473,12 +473,8 @@ // Returns the number of entries for `context_origin`, as determined by a // manual "COUNT(*)" query, rather than relying on the `length` recorded in - // `per_origin_mapping`. If `include_expired`, then the count is scoped to all - // entries; otherwise it is only scoped to entries within the lookback window - // determined by `staleness_threshold_`. Returns -1 if there is a database - // error. - [[nodiscard]] int64_t NumEntriesManualCount(const std::string& context_origin, - bool include_expired = false) + // `per_origin_mapping`. Returns -1 if there is a database error. + [[nodiscard]] int64_t NumEntriesManualCount(const std::string& context_origin) VALID_CONTEXT_REQUIRED(sequence_checker_); // Returns whether an entry exists for `context_origin` and `key`.
diff --git a/components/value_store/value_store_change.cc b/components/value_store/value_store_change.cc index 086d7fbc..da85bac8 100644 --- a/components/value_store/value_store_change.cc +++ b/components/value_store/value_store_change.cc
@@ -13,18 +13,18 @@ namespace value_store { base::Value ValueStoreChange::ToValue(ValueStoreChangeList changes) { - base::Value changes_value(base::Value::Type::DICTIONARY); + base::Value::Dict changes_dict; for (auto& change : changes) { - base::Value change_value(base::Value::Type::DICTIONARY); + base::Value::Dict change_dict; if (change.old_value) { - change_value.SetKey("oldValue", std::move(*change.old_value)); + change_dict.Set("oldValue", std::move(*change.old_value)); } if (change.new_value) { - change_value.SetKey("newValue", std::move(*change.new_value)); + change_dict.Set("newValue", std::move(*change.new_value)); } - changes_value.SetKey(change.key, std::move(change_value)); + changes_dict.Set(change.key, std::move(change_dict)); } - return changes_value; + return base::Value(std::move(changes_dict)); } ValueStoreChange::ValueStoreChange(const std::string& key,
diff --git a/components/value_store/value_store_change_unittest.cc b/components/value_store/value_store_change_unittest.cc index 7195a3a..219b0c5 100644 --- a/components/value_store/value_store_change_unittest.cc +++ b/components/value_store/value_store_change_unittest.cc
@@ -15,13 +15,13 @@ changes.push_back(ValueStoreChange("foo", absl::nullopt, base::Value("bar"))); changes.push_back(ValueStoreChange("baz", base::Value("qux"), absl::nullopt)); - base::Value expected(base::Value::Type::DICTIONARY); - base::Value expected_foo(base::Value::Type::DICTIONARY); - base::Value expected_baz(base::Value::Type::DICTIONARY); - expected_foo.SetStringKey("newValue", "bar"); - expected_baz.SetStringKey("oldValue", "qux"); - expected.SetKey("foo", std::move(expected_foo)); - expected.SetKey("baz", std::move(expected_baz)); + base::Value::Dict expected; + base::Value::Dict expected_foo; + base::Value::Dict expected_baz; + expected_foo.Set("newValue", "bar"); + expected_baz.Set("oldValue", "qux"); + expected.Set("foo", std::move(expected_foo)); + expected.Set("baz", std::move(expected_baz)); EXPECT_EQ(expected, ValueStoreChange::ToValue(std::move(changes))); }
diff --git a/components/value_store/value_store_test_suite.cc b/components/value_store/value_store_test_suite.cc index 164198f3..c4e23b3f 100644 --- a/components/value_store/value_store_test_suite.cc +++ b/components/value_store/value_store_test_suite.cc
@@ -77,7 +77,7 @@ TEST_P(ValueStoreTestSuite, NonexistentKeysReturnOk) { auto result = storage_->Get("key"); ASSERT_TRUE(result.status().ok()); - EXPECT_EQ(result.settings(), base::Value(base::Value::Type::DICTIONARY)); + EXPECT_EQ(result.settings(), base::Value::Dict()); } TEST_P(ValueStoreTestSuite, SetProducesMatchingChanges) {
diff --git a/content/BUILD.gn b/content/BUILD.gn index c96243b..3a8b6b03 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn
@@ -117,12 +117,8 @@ "dev_ui_content_resources.pak", ] deps = [ - "//components/attribution_reporting:mojom_js__generator", "//content/browser/aggregation_service:mojo_bindings_js__generator", - "//content/browser/attribution_reporting:internals_mojo_bindings_js__generator", - "//content/browser/attribution_reporting:mojo_bindings_js__generator", "//content/browser/resources/aggregation_service:build_ts", - "//content/browser/resources/attribution_reporting:build_ts", "//content/browser/resources/gpu:html_wrapper_files", "//content/browser/resources/process:build_ts", "//storage/browser/quota:mojo_bindings_js__generator",
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc index 1855eac..149d49c 100644 --- a/content/browser/accessibility/accessibility_action_browsertest.cc +++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -1239,7 +1239,7 @@ ASSERT_EQ(1U, target->PlatformChildCount()); BrowserAccessibility* popup_web_area = target->PlatformGetChild(0); - EXPECT_EQ(ax::mojom::Role::kRootWebArea, popup_web_area->GetRole()); + EXPECT_EQ(ax::mojom::Role::kGroup, popup_web_area->GetRole()); BrowserAccessibility* listbox = FindNode(ax::mojom::Role::kListBox, ""); ASSERT_TRUE(listbox); @@ -1274,7 +1274,7 @@ ASSERT_EQ(1U, target->PlatformChildCount()); BrowserAccessibility* popup_web_area = target->PlatformGetChild(0); - EXPECT_EQ(ax::mojom::Role::kRootWebArea, popup_web_area->GetRole()); + EXPECT_EQ(ax::mojom::Role::kGroup, popup_web_area->GetRole()); } #endif // BUILDFLAG(OS_WIN) || BUILDFLAG(OS_CHROMEOS) || BUILDFLAG(USE_ATK) } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 4ddf7e4..448e573 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -327,7 +327,7 @@ if (popup_root_ids_.size() == 1) { BrowserAccessibility* node = GetFromID(*popup_root_ids_.begin()); if (node) { - DCHECK(node->GetRole() == ax::mojom::Role::kRootWebArea); + DCHECK(node->GetRole() == ax::mojom::Role::kGroup); return node; } } @@ -1463,8 +1463,7 @@ id_wrapper_map_[node->id()] = BrowserAccessibility::Create(this, node); - if (tree->root() != node && - node->GetRole() == ax::mojom::Role::kRootWebArea) { + if (node->HasIntAttribute(ax::mojom::IntAttribute::kPopupForId)) { popup_root_ids_.insert(node->id()); } } @@ -1495,20 +1494,6 @@ wrapper->SetNode(*node); } -void BrowserAccessibilityManager::OnRoleChanged(ui::AXTree* tree, - ui::AXNode* node, - ax::mojom::Role old_role, - ax::mojom::Role new_role) { - DCHECK(node); - if (tree->root() == node) - return; - if (new_role == ax::mojom::Role::kRootWebArea) { - popup_root_ids_.insert(node->id()); - } else if (old_role == ax::mojom::Role::kRootWebArea) { - popup_root_ids_.erase(node->id()); - } -} - void BrowserAccessibilityManager::OnAtomicUpdateFinished( ui::AXTree* tree, bool root_changed,
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index e0061fc..45cb1a0 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -410,10 +410,6 @@ void OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) override; void OnNodeDeleted(ui::AXTree* tree, int32_t node_id) override; void OnNodeReparented(ui::AXTree* tree, ui::AXNode* node) override; - void OnRoleChanged(ui::AXTree* tree, - ui::AXNode* node, - ax::mojom::Role old_role, - ax::mojom::Role new_role) override; void OnAtomicUpdateFinished( ui::AXTree* tree, bool root_changed,
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc index b0c8691..60ef227 100644 --- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -1525,8 +1525,9 @@ ui::AXNodeData child_tree_root; child_tree_root.id = 3; - child_tree_root.role = ax::mojom::Role::kRootWebArea; - root.child_ids.push_back(3); + child_tree_root.role = ax::mojom::Role::kGroup; + child_tree_root.AddIntAttribute(ax::mojom::IntAttribute::kPopupForId, 2); + popup_button.child_ids.push_back(3); std::unique_ptr<BrowserAccessibilityManager> manager( BrowserAccessibilityManager::Create( @@ -1536,37 +1537,15 @@ ASSERT_NE(manager->GetPopupRoot(), nullptr); EXPECT_EQ(manager->GetPopupRoot()->GetId(), 3); - // Update tree to change the role of the nested child root, add new child root - // in same update. - child_tree_root.role = ax::mojom::Role::kGroup; - ui::AXNodeData second_child_tree_root; - second_child_tree_root.id = 4; - second_child_tree_root.role = ax::mojom::Role::kRootWebArea; - root.child_ids.push_back(4); - - manager->Initialize(MakeAXTreeUpdateForTesting(root, child_tree_root, - second_child_tree_root)); - - ASSERT_NE(manager->GetPopupRoot(), nullptr); - EXPECT_EQ(manager->GetPopupRoot()->GetId(), 4); - - // Update tree to change the role of the nested child root, so that there is - // no longer any nested child root. - second_child_tree_root.role = ax::mojom::Role::kGroup; - manager->Initialize(MakeAXTreeUpdateForTesting(second_child_tree_root)); - EXPECT_EQ(manager->GetPopupRoot(), nullptr); - // Test deleting child root. - // First, ensure a child root exists. - second_child_tree_root.role = ax::mojom::Role::kRootWebArea; - manager->Initialize(MakeAXTreeUpdateForTesting(second_child_tree_root)); - ASSERT_NE(manager->GetPopupRoot(), nullptr); - EXPECT_EQ(manager->GetPopupRoot()->GetId(), 4); - // Now remove the child root from the tree. - root.child_ids = {2, 3}; - manager->Initialize(MakeAXTreeUpdateForTesting(root)); + popup_button.child_ids = {}; + ui::AXTreeUpdate update = MakeAXTreeUpdateForTesting(popup_button); + AXEventNotificationDetails events; + events.updates = {update}; + ASSERT_TRUE(manager->OnAccessibilityEvents(events)); + EXPECT_EQ(manager->GetPopupRoot(), nullptr); }
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc index 98cca66..7d5aaca2 100644 --- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc +++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -1588,7 +1588,7 @@ const BrowserAccessibility* popup_area = manager->GetFromID(controls_ids[1]); ASSERT_NE(nullptr, popup_area); - EXPECT_EQ(ax::mojom::Role::kRootWebArea, popup_area->GetRole()); + EXPECT_EQ(ax::mojom::Role::kGroup, popup_area->GetRole()); #if !BUILDFLAG(IS_CASTOS) && !BUILDFLAG(IS_CAST_ANDROID) // Ensure that the bounding box of the popup area is at least 100 @@ -1653,7 +1653,7 @@ const BrowserAccessibility* popup_area = manager->GetFromID(controls_ids[0]); ASSERT_NE(nullptr, popup_area); - EXPECT_EQ(ax::mojom::Role::kRootWebArea, popup_area->GetRole()); + EXPECT_EQ(ax::mojom::Role::kGroup, popup_area->GetRole()); } }
diff --git a/content/browser/attribution_reporting/attribution_internals_browsertest.cc b/content/browser/attribution_reporting/attribution_internals_browsertest.cc index 3c9b50f1..2f7d6d7 100644 --- a/content/browser/attribution_reporting/attribution_internals_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_internals_browsertest.cc
@@ -323,9 +323,11 @@ table.children[1].children[14]?.innerText === '' && table.children[4].children[14]?.innerText === 'Cleared (was 987)' && table.children[0].children[15]?.innerText === '' && - table.children[1].children[15]?.innerText === '13, 17' && + table.children[1].children[15]?.children[0]?.children[0]?.innerText === '13' && + table.children[1].children[15]?.children[0]?.children[1]?.innerText === '17' && table.children[0].children[16]?.innerText === '' && - table.children[1].children[16]?.innerText === '14, 18' && + table.children[1].children[16]?.children[0]?.children[0]?.innerText === '14' && + table.children[1].children[16]?.children[0]?.children[1]?.innerText === '18' && table.children[0].children[1]?.innerText === 'Unattributable: noised' && table.children[1].children[1]?.innerText === 'Attributable' && table.children[2].children[1]?.innerText === 'Attributable: reached event-level attribution limit' &&
diff --git a/content/browser/attribution_reporting/attribution_internals_ui.cc b/content/browser/attribution_reporting/attribution_internals_ui.cc index 1e2d6f8..be5c463 100644 --- a/content/browser/attribution_reporting/attribution_internals_ui.cc +++ b/content/browser/attribution_reporting/attribution_internals_ui.cc
@@ -4,8 +4,10 @@ #include "content/browser/attribution_reporting/attribution_internals_ui.h" +#include "base/containers/span.h" #include "content/browser/attribution_reporting/attribution_internals_handler_impl.h" -#include "content/grit/dev_ui_content_resources.h" +#include "content/grit/attribution_internals_resources.h" +#include "content/grit/attribution_internals_resources_map.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -25,23 +27,12 @@ web_ui->GetWebContents()->GetBrowserContext(), kChromeUIAttributionInternalsHost); - source->AddResourcePath("attribution_internals.mojom-webui.js", - IDR_ATTRIBUTION_INTERNALS_MOJOM_JS); - source->AddResourcePath("attribution_internals.js", - IDR_ATTRIBUTION_INTERNALS_JS); - source->AddResourcePath("attribution_internals_table.js", - IDR_ATTRIBUTION_INTERNALS_TABLE_JS); - source->AddResourcePath("attribution_internals_table.html.js", - IDR_ATTRIBUTION_INTERNALS_TABLE_HTML_JS); - source->AddResourcePath("attribution_reporting.mojom-webui.js", - IDR_ATTRIBUTION_REPORTING_MOJOM_JS); - source->AddResourcePath("source_registration_error.mojom-webui.js", - IDR_SOURCE_REGISTRATION_ERROR_MOJOM_JS); - source->AddResourcePath("table_model.js", - IDR_ATTRIBUTION_INTERNALS_TABLE_MODEL_JS); - source->AddResourcePath("attribution_internals.css", - IDR_ATTRIBUTION_INTERNALS_CSS); - source->SetDefaultResource(IDR_ATTRIBUTION_INTERNALS_HTML); + source->AddResourcePaths(base::make_span(kAttributionInternalsResources, + kAttributionInternalsResourcesSize)); + + source->SetDefaultResource( + IDR_ATTRIBUTION_INTERNALS_ATTRIBUTION_INTERNALS_HTML); + source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::TrustedTypes, "trusted-types static-types;");
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index 3829d37..46ce25c 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -83,6 +83,7 @@ namespace { using ::testing::Eq; +using ::testing::HasSubstr; using ::testing::Optional; // Returned by test Javascript code when join or leave promises complete without @@ -1194,21 +1195,21 @@ bool ReplaceInURNInJS( const GURL& urn_url, const base::flat_map<std::string, std::string> replacements, - const absl::optional<ToRenderFrameHost> execution_target = - absl::nullopt) { + std::string* error_out = nullptr) { base::Value::Dict replacement_value; for (const auto& replacement : replacements) replacement_value.Set(replacement.first, replacement.second); - EvalJsResult result = - EvalJs(execution_target ? *execution_target : shell(), - JsReplace(R"( + EvalJsResult result = EvalJs( + shell(), JsReplace(R"( (async function() { await navigator.deprecatedReplaceInURN($1, $2); return 'done'; })())", - urn_url, base::Value(std::move(replacement_value)))); - EXPECT_EQ("", result.error); - return "done" == result; + urn_url, base::Value(std::move(replacement_value)))); + if (error_out != nullptr) { + *error_out = result.error; + } + return result.error == "" && result == "done"; } void AttachInterestGroupObserver() { @@ -4107,6 +4108,33 @@ NavigateIframeAndCheckURL(web_contents(), urn_url, expected_ad_url); } +IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, + ReplaceURLFailsOnBadReplacementInput) { + GURL test_url = https_server_->GetURL("a.test", "/page_with_iframe.html"); + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + + GURL urn_url = GURL("urn:uuid:84a8bf15-8539-432d-bb9f-4eb20eaf400b"); + std::string error; + EXPECT_FALSE(ReplaceInURNInJS( + urn_url, {{"${INTEREST_GROUP_NAME}", "render_cars"}, {"%echo%%", "echo"}}, + &error)); + EXPECT_THAT(error, HasSubstr("Replacements must be of the form ")); +} + +IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest, + ReplaceURLFailsOnMalformedURN) { + GURL test_url = https_server_->GetURL("a.test", "/page_with_iframe.html"); + ASSERT_TRUE(NavigateToURL(shell(), test_url)); + + GURL urn_url = GURL("http://test.com"); + std::string error; + EXPECT_FALSE(ReplaceInURNInJS( + urn_url, + {{"${INTEREST_GROUP_NAME}", "render_cars"}, {"%%echo%%", "echo"}}, + &error)); + EXPECT_THAT(error, HasSubstr("Passed URL must be a valid URN URL.")); +} + IN_PROC_BROWSER_TEST_F( InterestGroupBrowserTest, RunAdAuctionPerBuyerSignalsAndPerBuyerTimeoutsOriginNotInBuyers) { @@ -4838,7 +4866,8 @@ << "URL is not valid: " << urn_url_string.ExtractString(); EXPECT_EQ(url::kUrnScheme, urn_url.scheme_piece()); - ReplaceInURNInJS(urn_url, {{"%%LOADING_MODE%%", "fenced-frame"}}); + EXPECT_TRUE( + ReplaceInURNInJS(urn_url, {{"%%LOADING_MODE%%", "fenced-frame"}})); NavigateFencedFrameAndWait(urn_url, expected_ad_url, shell()); }
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm index 476a8e6..dc28dc53 100644 --- a/content/browser/media/capture/screen_capture_kit_device_mac.mm +++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
@@ -66,16 +66,24 @@ if (attachment) { CFDictionaryRef contentRectValue = base::mac::CFCast<CFDictionaryRef>( CFDictionaryGetValue(attachment, SCStreamFrameInfoContentRect)); + CFNumberRef scaleFactorValue = base::mac::CFCast<CFNumberRef>( + CFDictionaryGetValue(attachment, SCStreamFrameInfoScaleFactor)); CFNumberRef contentScaleValue = base::mac::CFCast<CFNumberRef>( CFDictionaryGetValue(attachment, SCStreamFrameInfoContentScale)); - if (contentRectValue && contentScaleValue) { + + if (contentRectValue && scaleFactorValue && contentScaleValue) { CGRect contentRect = {}; bool succeed = CGRectMakeWithDictionaryRepresentation(contentRectValue, &contentRect); + float scaleFactor = 1.0f; + succeed &= CFNumberGetValue(scaleFactorValue, kCFNumberFloatType, + &scaleFactor); float contentScale = 1.0f; succeed &= CFNumberGetValue(contentScaleValue, kCFNumberFloatType, &contentScale); if (succeed) { + contentRect.size.width *= scaleFactor; + contentRect.size.height *= scaleFactor; visibleRect.emplace(contentRect); contentSize.emplace(round(contentRect.size.width / contentScale), round(contentRect.size.height / contentScale)); @@ -267,8 +275,11 @@ } } else { // No current request for new capture format. Check to see if content_size - // has changed and requires an updated configuration. - if (content_size && + // has changed and requires an updated configuration. We only track the + // content size for window capturing since the resolution does not + // normally change during a session and because the content scale is wrong + // for retina displays. + if (source_.type == DesktopMediaID::TYPE_WINDOW && content_size && (stream_config_content_size_.width() != content_size->width() || stream_config_content_size_.height() != content_size->height())) { DVLOG(3) << "Content size changed to " << content_size->width() << " x "
diff --git a/content/browser/resources/BUILD.gn b/content/browser/resources/BUILD.gn index 30b024e..462de0d 100644 --- a/content/browser/resources/BUILD.gn +++ b/content/browser/resources/BUILD.gn
@@ -4,6 +4,7 @@ group("resources") { public_deps = [ + "attribution_reporting:resources", "indexed_db:resources", "quota:resources", ]
diff --git a/content/browser/resources/attribution_reporting/BUILD.gn b/content/browser/resources/attribution_reporting/BUILD.gn index 61040daf..6f1bec62 100644 --- a/content/browser/resources/attribution_reporting/BUILD.gn +++ b/content/browser/resources/attribution_reporting/BUILD.gn
@@ -2,53 +2,44 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//tools/polymer/html_to_wrapper.gni") -import("//tools/typescript/ts_library.gni") +import("//chrome/browser/resources/tools/build_webui.gni") -html_to_wrapper("html_wrapper_files") { - in_files = [ "attribution_internals_table.html" ] - template = "native" -} +build_webui("build") { + grd_prefix = "attribution_internals" -# Copy (via creating sym links) all the other files into the same folder for -# ts_library. -copy("copy_files") { - deps = [ - "//components/attribution_reporting:mojom_js__generator", - "//content/browser/attribution_reporting:internals_mojo_bindings_js__generator", - "//content/browser/attribution_reporting:mojo_bindings_js__generator", + static_files = [ + "attribution_internals.html", + "attribution_internals.css", ] - sources = [ - "$root_gen_dir/mojom-webui/components/attribution_reporting/source_registration_error.mojom-webui.js", - "$root_gen_dir/mojom-webui/content/browser/attribution_reporting/attribution_internals.mojom-webui.js", - "$root_gen_dir/mojom-webui/content/browser/attribution_reporting/attribution_reporting.mojom-webui.js", + + non_web_component_files = [ "attribution_internals.ts", - "attribution_internals_table.ts", "table_model.ts", ] - outputs = [ "$target_gen_dir/{{source_file_part}}" ] -} -ts_library("build_ts") { - root_dir = target_gen_dir - out_dir = "$target_gen_dir/tsc" - tsconfig_base = "tsconfig_base.json" - in_files = [ - "attribution_internals.ts", - "attribution_internals_table.ts", - "attribution_internals_table.html.ts", - "table_model.ts", - "attribution_internals.mojom-webui.js", - "attribution_reporting.mojom-webui.js", - "source_registration_error.mojom-webui.js", - ] - deps = [ + web_component_files = [ "attribution_internals_table.ts" ] + + ts_deps = [ "//ui/webui/resources:library", "//ui/webui/resources/mojo:library", ] - definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] - extra_deps = [ - ":copy_files", - ":html_wrapper_files", + + mojom_folder = "$root_gen_dir/mojom-webui" + attribution_reporting_component_folder = "components/attribution_reporting" + attribution_reporting_content_folder = "content/browser/attribution_reporting" + + mojo_files = [ + "$mojom_folder/$attribution_reporting_component_folder/source_registration_error.mojom-webui.js", + "$mojom_folder/$attribution_reporting_content_folder/attribution_internals.mojom-webui.js", + "$mojom_folder/$attribution_reporting_content_folder/attribution_reporting.mojom-webui.js", ] + + mojo_files_deps = [ + "//$attribution_reporting_component_folder:mojom_js__generator", + "//$attribution_reporting_content_folder:internals_mojo_bindings_js__generator", + "//$attribution_reporting_content_folder:mojo_bindings_js__generator", + ] + + grit_output_dir = "$root_gen_dir/content" + html_to_wrapper_template = "native" }
diff --git a/content/browser/resources/attribution_reporting/attribution_internals.ts b/content/browser/resources/attribution_reporting/attribution_internals.ts index 1317345..36074e0 100644 --- a/content/browser/resources/attribution_reporting/attribution_internals.ts +++ b/content/browser/resources/attribution_reporting/attribution_internals.ts
@@ -79,6 +79,29 @@ } } +class ListColumn<T, V> extends ValueColumn<T, V[]> { + constructor(header: string, getValue: (p: T) => V[]) { + super(header, getValue, /*comparable=*/ false); + } + + override render(td: HTMLElement, row: T) { + const values = this.getValue(row); + if (values.length === 0) { + return; + } + + const ul = td.ownerDocument.createElement('ul'); + + values.forEach(value => { + const li = td.ownerDocument.createElement('li'); + li.innerText = `${value}`; + ul.appendChild(li); + }); + + td.appendChild(ul); + } +} + function renderDL<T>(td: HTMLElement, row: T, cols: Array<Column<T>>) { const dl = td.ownerDocument.createElement('dl'); @@ -236,11 +259,11 @@ filterData: string; aggregationKeys: string; debugKey: string; - dedupKeys: string; + dedupKeys: bigint[]; priority: bigint; status: string; aggregatableBudgetConsumed: bigint; - aggregatableDedupKeys: string; + aggregatableDedupKeys: bigint[]; debugReportingEnabled: string; constructor(mojo: WebUISource) { @@ -267,9 +290,9 @@ this.debugKey = ''; } - this.dedupKeys = mojo.dedupKeys.join(', '); + this.dedupKeys = mojo.dedupKeys; this.aggregatableBudgetConsumed = mojo.aggregatableBudgetConsumed; - this.aggregatableDedupKeys = mojo.aggregatableDedupKeys.join(', '); + this.aggregatableDedupKeys = mojo.aggregatableDedupKeys; this.status = attributabilityToText(mojo.attributability); this.debugReportingEnabled = sourceDebugReportingToText(mojo.debugReportingEnabled); } @@ -307,8 +330,8 @@ 'Aggregatable Budget Consumed', (e) => `${e.aggregatableBudgetConsumed} / ${BUDGET_PER_SOURCE}`), new ValueColumn<Source, string>('Debug Key', (e) => e.debugKey), - new ValueColumn<Source, string>('Dedup Keys', (e) => e.dedupKeys), - new ValueColumn<Source, string>( + new ListColumn<Source, bigint>('Dedup Keys', (e) => e.dedupKeys), + new ListColumn<Source, bigint>( 'Aggregatable Dedup Keys', (e) => e.aggregatableDedupKeys), new ValueColumn<Source, string>( 'Verbose Debug Reporting', (e) => e.debugReportingEnabled),
diff --git a/content/dev_ui_content_resources.grd b/content/dev_ui_content_resources.grd index 59fed7d..e84b586 100644 --- a/content/dev_ui_content_resources.grd +++ b/content/dev_ui_content_resources.grd
@@ -22,14 +22,6 @@ <include name="IDR_AGGREGATION_SERVICE_INTERNALS_TABLE_HTML_JS" file="${root_gen_dir}/content/browser/resources/aggregation_service/tsc/aggregation_service_internals_table.html.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_AGGREGATION_SERVICE_INTERNALS_CSS" file="browser/resources/aggregation_service/aggregation_service_internals.css" type="BINDATA" /> <include name="IDR_AGGREGATION_SERVICE_INTERNALS_MOJOM_JS" file="${root_gen_dir}/mojom-webui/content/browser/aggregation_service/aggregation_service_internals.mojom-webui.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_HTML" file="browser/resources/attribution_reporting/attribution_internals.html" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_JS" file="${root_gen_dir}/content/browser/resources/attribution_reporting/tsc/attribution_internals.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_TABLE_MODEL_JS" file="${root_gen_dir}/content/browser/resources/attribution_reporting/tsc/table_model.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_TABLE_JS" file="${root_gen_dir}/content/browser/resources/attribution_reporting/tsc/attribution_internals_table.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_TABLE_HTML_JS" file="${root_gen_dir}/content/browser/resources/attribution_reporting/tsc/attribution_internals_table.html.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_CSS" file="browser/resources/attribution_reporting/attribution_internals.css" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_INTERNALS_MOJOM_JS" file="${root_gen_dir}/mojom-webui/content/browser/attribution_reporting/attribution_internals.mojom-webui.js" use_base_dir="false" type="BINDATA" /> - <include name="IDR_ATTRIBUTION_REPORTING_MOJOM_JS" file="${root_gen_dir}/mojom-webui/content/browser/attribution_reporting/attribution_reporting.mojom-webui.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_GPU_BROWSER_BRIDGE_JS" file="browser/resources/gpu/browser_bridge.js" type="BINDATA" /> <include name="IDR_GPU_INTERNALS_HTML" file="browser/resources/gpu/gpu_internals.html" type="BINDATA" /> <include name="IDR_GPU_INTERNALS_JS" file="browser/resources/gpu/gpu_internals.js" type="BINDATA" /> @@ -50,7 +42,6 @@ <include name="IDR_SERVICE_WORKER_INTERNALS_HTML" file="browser/resources/service_worker/serviceworker_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_SERVICE_WORKER_INTERNALS_JS" file="browser/resources/service_worker/serviceworker_internals.js" type="BINDATA" /> <include name="IDR_SERVICE_WORKER_INTERNALS_CSS" file="browser/resources/service_worker/serviceworker_internals.css" type="BINDATA" /> - <include name="IDR_SOURCE_REGISTRATION_ERROR_MOJOM_JS" file="${root_gen_dir}/mojom-webui/components/attribution_reporting/source_registration_error.mojom-webui.js" use_base_dir="false" type="BINDATA" /> </includes> </release> </grit>
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 6eb90ad..d439be4 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -28,15 +28,10 @@ "//ui/android:ui_java_resources", ] sources = [ - "java/res/drawable-hdpi/ic_menu_share_holo_light.png", "java/res/drawable-hdpi/ic_search.png", - "java/res/drawable-mdpi/ic_menu_share_holo_light.png", "java/res/drawable-mdpi/ic_search.png", - "java/res/drawable-xhdpi/ic_menu_share_holo_light.png", "java/res/drawable-xhdpi/ic_search.png", - "java/res/drawable-xxhdpi/ic_menu_share_holo_light.png", "java/res/drawable-xxhdpi/ic_search.png", - "java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png", "java/res/drawable-xxxhdpi/ic_search.png", "java/res/drawable/floating_popup_background.xml", "java/res/layout-land/date_time_picker_dialog.xml", @@ -48,11 +43,10 @@ "java/res/layout/text_edit_suggestion_list_footer.xml", "java/res/layout/two_field_date_picker.xml", "java/res/menu/select_action_menu.xml", - "java/res/values-v17/styles.xml", - "java/res/values-v21/styles.xml", "java/res/values/attrs.xml", "java/res/values/dimens.xml", "java/res/values/strings.xml", + "java/res/values/styles.xml", ] }
diff --git a/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png b/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png deleted file mode 100644 index 5c7406e..0000000 --- a/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png +++ /dev/null Binary files differ
diff --git a/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png b/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png deleted file mode 100644 index 8053569..0000000 --- a/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png +++ /dev/null Binary files differ
diff --git a/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png b/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png deleted file mode 100644 index c8f19ee..0000000 --- a/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png +++ /dev/null Binary files differ
diff --git a/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png b/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png deleted file mode 100644 index af433b4..0000000 --- a/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png +++ /dev/null Binary files differ
diff --git a/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png b/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png deleted file mode 100644 index 796c843..0000000 --- a/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png +++ /dev/null Binary files differ
diff --git a/content/public/android/java/res/values-v21/styles.xml b/content/public/android/java/res/values-v21/styles.xml deleted file mode 100644 index 05bd8e3..0000000 --- a/content/public/android/java/res/values-v21/styles.xml +++ /dev/null
@@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2014 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<resources> - <style name="SelectActionMenuShare"> - <item name="android:icon">?android:attr/actionModeShareDrawable</item> - </style> - <style name="SelectActionMenuWebSearch"> - <item name="android:icon">?android:attr/actionModeWebSearchDrawable</item> - </style> - <style name="TextAppearance.TextSuggestionButton"> - <item name="android:drawablePadding">8dp</item> - <item name="android:gravity">start|center_vertical</item> - <item name="android:layout_gravity">start|center_vertical</item> - <item name="android:layout_height">48dp</item> - <item name="android:layout_width">match_parent</item> - <item name="android:paddingBottom">8dp</item> - <item name="android:paddingEnd">16dp</item> - <item name="android:paddingStart">16dp</item> - <item name="android:paddingTop">8dp</item> - <item name="android:singleLine">true</item> - <!-- v17 hard codes modern_blue_600 --> - <item name="android:textAppearance">@style/TextAppearance.TextSuggestionButtonText</item> - </style> - - <style name="TextAppearance.TextSuggestionButtonText" parent="@style/TextAppearance.Button.Text.Blue"> - <item name="android:textColor">?android:attr/colorAccent</item> - </style> -</resources>
diff --git a/content/public/android/java/res/values-v17/styles.xml b/content/public/android/java/res/values/styles.xml similarity index 78% rename from content/public/android/java/res/values-v17/styles.xml rename to content/public/android/java/res/values/styles.xml index fcccab94..800d8857 100644 --- a/content/public/android/java/res/values-v17/styles.xml +++ b/content/public/android/java/res/values/styles.xml
@@ -11,17 +11,16 @@ <item name="select_dialog_multichoice">@android:layout/select_dialog_multichoice</item> </style> <style name="SelectActionMenuShare"> - <item name="android:icon">@drawable/ic_menu_share_holo_light</item> + <item name="android:icon">?android:attr/actionModeShareDrawable</item> </style> <style name="SelectActionMenuWebSearch"> - <item name="android:icon">@drawable/ic_search</item> + <item name="android:icon">?android:attr/actionModeWebSearchDrawable</item> </style> <style name="TextAppearance.SuggestionPrefixOrSuffix"> <item name="android:textColor">?android:attr/textColorSecondary</item> </style> <style name="TextAppearance.TextSuggestionButton"> <item name="android:drawablePadding">8dp</item> - <!-- v21 uses sans-serif-medium --> <item name="android:gravity">start|center_vertical</item> <item name="android:layout_gravity">start|center_vertical</item> <item name="android:layout_height">48dp</item> @@ -31,7 +30,9 @@ <item name="android:paddingStart">16dp</item> <item name="android:paddingTop">8dp</item> <item name="android:singleLine">true</item> - <!-- v21 uses android:attr/colorAccent --> - <item name="android:textAppearance">@style/TextAppearance.Button.Text.Blue</item> + <item name="android:textAppearance">@style/TextAppearance.TextSuggestionButtonText</item> + </style> + <style name="TextAppearance.TextSuggestionButtonText" parent="@style/TextAppearance.Button.Text.Blue"> + <item name="android:textColor">?android:attr/colorAccent</item> </style> </resources>
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h index b132d649..7eaed5e 100644 --- a/content/public/renderer/render_frame_observer.h +++ b/content/public/renderer/render_frame_observer.h
@@ -307,6 +307,12 @@ virtual void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) {} + // Called when an image ad rectangle changed. An empty `image_ad_rect` is used + // to signal the removal of the rectangle. Only invoked on the main frame. + virtual void OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) {} + // Overlay-popup-ad violates The Better Ads Standards // (https://www.betterads.org/standards/). This method will be called when an // overlay-popup-ad is detected, to let the embedder
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index a1f691c..2a2410d 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -72,10 +72,6 @@ "media/audio_decoder.h", "media/batching_media_log.cc", "media/batching_media_log.h", - "media/codec_factory.cc", - "media/codec_factory.h", - "media/codec_factory_mojo.cc", - "media/codec_factory_mojo.h", "media/gpu/gpu_video_accelerator_factories_impl.cc", "media/gpu/gpu_video_accelerator_factories_impl.h", "media/inspector_media_event_handler.cc", @@ -344,11 +340,7 @@ } if (is_fuchsia) { - sources += [ - "media/codec_factory_fuchsia.cc", - "media/codec_factory_fuchsia.h", - "renderer_main_platform_delegate_fuchsia.cc", - ] + sources += [ "renderer_main_platform_delegate_fuchsia.cc" ] public_deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec" ] deps += [
diff --git a/content/renderer/media/codec_factory.cc b/content/renderer/media/codec_factory.cc deleted file mode 100644 index 65939e76..0000000 --- a/content/renderer/media/codec_factory.cc +++ /dev/null
@@ -1,224 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/codec_factory.h" - -#include <memory> -#include <optional> - -#include "base/functional/callback_forward.h" -#include "base/memory/ptr_util.h" -#include "base/notreached.h" -#include "media/base/bind_to_current_loop.h" -#include "media/base/decoder.h" -#include "media/base/media_log.h" -#include "media/base/overlay_info.h" -#include "media/base/supported_video_decoder_config.h" -#include "media/mojo/clients/mojo_video_encode_accelerator.h" -#include "media/video/gpu_video_accelerator_factories.h" - -namespace content { - -CodecFactory::CodecFactory( - scoped_refptr<base::SequencedTaskRunner> media_task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote) - : media_task_runner_(std::move(media_task_runner)), - context_provider_(std::move(context_provider)), - video_decode_accelerator_enabled_(video_decode_accelerator_enabled), - video_encode_accelerator_enabled_(video_encode_accelerator_enabled) { - media_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&CodecFactory::BindOnTaskRunner, base::Unretained(this), - std::move(pending_vea_provider_remote))); -} -CodecFactory::~CodecFactory() = default; - -std::unique_ptr<media::VideoEncodeAccelerator> -CodecFactory::CreateVideoEncodeAccelerator() { - DCHECK(video_encode_accelerator_enabled_); - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(vea_provider_.is_bound()); - - base::AutoLock lock(supported_profiles_lock_); - // When |supported_vea_profiles_| is empty, no hw encoder is available or - // we have not yet gotten the supported profiles. - if (!supported_vea_profiles_) { - DVLOG(2) << "VEA's profiles have not yet been gotten"; - } else if (supported_vea_profiles_->empty()) { - // There is no profile supported by VEA. - return nullptr; - } - - mojo::PendingRemote<media::mojom::VideoEncodeAccelerator> vea; - vea_provider_->CreateVideoEncodeAccelerator( - vea.InitWithNewPipeAndPassReceiver()); - - if (!vea) { - return nullptr; - } - - return base::WrapUnique<media::VideoEncodeAccelerator>( - new media::MojoVideoEncodeAccelerator(std::move(vea))); -} - -media::VideoDecoderType CodecFactory::GetVideoDecoderType() { - base::AutoLock lock(supported_profiles_lock_); - return video_decoder_type_; -} - -absl::optional<media::SupportedVideoDecoderConfigs> -CodecFactory::GetSupportedVideoDecoderConfigs() { - base::AutoLock lock(supported_profiles_lock_); - return supported_decoder_configs_; -} - -absl::optional<media::VideoEncodeAccelerator::SupportedProfiles> -CodecFactory::GetVideoEncodeAcceleratorSupportedProfiles() { - base::AutoLock lock(supported_profiles_lock_); - return supported_vea_profiles_; -} - -bool CodecFactory::IsDecoderSupportKnown() { - base::AutoLock lock(supported_profiles_lock_); - return decoder_support_notifier_.is_notified(); -} - -bool CodecFactory::IsEncoderSupportKnown() { - base::AutoLock lock(supported_profiles_lock_); - return encoder_support_notifier_.is_notified(); -} - -void CodecFactory::NotifyDecoderSupportKnown(base::OnceClosure callback) { - base::AutoLock lock(supported_profiles_lock_); - decoder_support_notifier_.Register( - media::BindToCurrentLoop(std::move(callback))); -} - -void CodecFactory::NotifyEncoderSupportKnown(base::OnceClosure callback) { - base::AutoLock lock(supported_profiles_lock_); - encoder_support_notifier_.Register( - media::BindToCurrentLoop(std::move(callback))); -} - -CodecFactory::Notifier::Notifier() = default; -CodecFactory::Notifier::~Notifier() = default; - -void CodecFactory::Notifier::Register(base::OnceClosure callback) { - if (is_notified_) { - std::move(callback).Run(); - return; - } - callbacks_.push_back(std::move(callback)); -} - -void CodecFactory::Notifier::Notify() { - DCHECK(!is_notified_); - is_notified_ = true; - while (!callbacks_.empty()) { - std::move(callbacks_.back()).Run(); - callbacks_.pop_back(); - } -} - -void CodecFactory::OnDecoderSupportFailed() { - base::AutoLock lock(supported_profiles_lock_); - if (decoder_support_notifier_.is_notified()) { - return; - } - supported_decoder_configs_ = media::SupportedVideoDecoderConfigs(); - decoder_support_notifier_.Notify(); -} - -void CodecFactory::OnGetSupportedDecoderConfigs() { - base::AutoLock lock(supported_profiles_lock_); - decoder_support_notifier_.Notify(); -} - -void CodecFactory::OnEncoderSupportFailed() { - base::AutoLock lock(supported_profiles_lock_); - if (encoder_support_notifier_.is_notified()) { - return; - } - supported_vea_profiles_ = media::VideoEncodeAccelerator::SupportedProfiles(); - encoder_support_notifier_.Notify(); -} - -void CodecFactory::OnGetVideoEncodeAcceleratorSupportedProfiles( - const media::VideoEncodeAccelerator::SupportedProfiles& - supported_profiles) { - base::AutoLock lock(supported_profiles_lock_); - supported_vea_profiles_ = supported_profiles; - encoder_support_notifier_.Notify(); -} - -void CodecFactory::BindOnTaskRunner( - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote) { - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(context_provider_); - - vea_provider_.Bind(std::move(pending_vea_provider_remote)); - - if (context_provider_->BindToCurrentSequence() != - gpu::ContextResult::kSuccess) { - OnDecoderSupportFailed(); - OnEncoderSupportFailed(); - return; - } - - if (video_encode_accelerator_enabled_) { - // The remote might be disconnected if the encoding process crashes, for - // example a GPU driver failure. Set a disconnect handler to watch these - // types of failures and treat them as if there are no supported encoder - // profiles. - // Unretained is safe since CodecFactory is never destroyed. - // It lives until the process shuts down. - vea_provider_.set_disconnect_handler(base::BindOnce( - &CodecFactory::OnEncoderSupportFailed, base::Unretained(this))); - vea_provider_->GetVideoEncodeAcceleratorSupportedProfiles(base::BindOnce( - &CodecFactory::OnGetVideoEncodeAcceleratorSupportedProfiles, - base::Unretained(this))); - } else { - OnEncoderSupportFailed(); - } - - if (!video_decode_accelerator_enabled_) { - OnDecoderSupportFailed(); - } -} - -CodecFactoryDefault::CodecFactoryDefault( - scoped_refptr<base::SequencedTaskRunner> task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote) - : CodecFactory(std::move(task_runner), - std::move(context_provider), - video_decode_accelerator_enabled, - video_encode_accelerator_enabled, - std::move(pending_vea_provider_remote)) { - // There is no decoder provider. - OnDecoderSupportFailed(); -} - -CodecFactoryDefault::~CodecFactoryDefault() = default; - -std::unique_ptr<media::VideoDecoder> CodecFactoryDefault::CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) { - NOTIMPLEMENTED() - << "CodecFactoryDefault does not have a provider to create a " - "hardware video decoder."; - return nullptr; -} - -} // namespace content
diff --git a/content/renderer/media/codec_factory.h b/content/renderer/media/codec_factory.h deleted file mode 100644 index 55e1374..0000000 --- a/content/renderer/media/codec_factory.h +++ /dev/null
@@ -1,196 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_CODEC_FACTORY_H_ -#define CONTENT_RENDERER_MEDIA_CODEC_FACTORY_H_ - -#include <memory> - -#include "base/functional/callback_forward.h" -#include "content/common/content_export.h" -#include "media/base/decoder.h" -#include "media/base/media_log.h" -#include "media/base/overlay_info.h" -#include "media/base/supported_video_decoder_config.h" -#include "media/base/video_decoder.h" -#include "media/mojo/mojom/video_encode_accelerator.mojom.h" -#include "media/video/gpu_video_accelerator_factories.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h" - -namespace content { - -// Assists to GpuVideoAcceleratorFactoriesImpl on hardware decoder and encoder -// functionalities. -// -// It is a base class that handles the encoder resources -// via media::mojom::VideoEncodeAcceleratorProvider. Its derived classes need -// to implement how to connect to hardware decoder resources. -class CONTENT_EXPORT CodecFactory { - public: - // `media_task_runner` - task runner for running multi-media operations. - // `context_provider` - context provider for creating a video decoder. - // `video_decode_accelerator_enabled` - whether the video decode accelerator - // is enabled. - // `video_encode_accelerator_enabled` - whether the video encode accelerator - // is enabled. - // `pending_vea_provider_remote` - bound pending - // media::mojom::VideoEncodeAcceleratorProvider remote. - CodecFactory( - scoped_refptr<base::SequencedTaskRunner> media_task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote); - - CodecFactory(const CodecFactory&) = delete; - CodecFactory& operator=(const CodecFactory&) = delete; - virtual ~CodecFactory(); - - // `gpu_factories` - pointer to the GpuVideoAcceleratorFactories that - // owns |this|. - // `media_log` - process-wide pointer to log to chrome://media-internals log. - // `request_overlay_info_cb` - callback that gets the overlay information. - // `rendering_color_space` - color space for the purpose of color conversion. - // - // Derived class should construct its own type of video decoder. - virtual std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) = 0; - - std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator(); - - // Returns VideoDecoderType::kUnknown in cases where IsDecoderSupportKnown() - // is false. - // Otherwise, it returns the type of decoder that provided the - // configs for the config support check. - media::VideoDecoderType GetVideoDecoderType(); - - // Returns a nullopt if we have not yet gotten the configs. - // Returns an optional that contains an empty vector if we have gotten the - // result and there are no supported configs. - absl::optional<media::SupportedVideoDecoderConfigs> - GetSupportedVideoDecoderConfigs(); - - // Returns a nullopt if we have not yet gotten the profiles. - // Returns an optional that contains an empty vector if we have gotten the - // result and there are no supported profiles. - absl::optional<media::VideoEncodeAccelerator::SupportedProfiles> - GetVideoEncodeAcceleratorSupportedProfiles(); - - // Returns true if media::SupportedVideoDecoderConfigs are populated. - bool IsDecoderSupportKnown(); - - // Returns true if media::VideoEncodeAccelerator::SupportedProfiles are - // populated. - bool IsEncoderSupportKnown(); - - // If the current decoder support is not yet known, use this to register a - // callback that is notified once the support is known. At that point, calling - // GetSupportedVideoDecoderConfigs will give the set of supported decoder - // configs. - // - // There is no way to unsubscribe a callback, it is recommended to use a - // WeakPtr if you need this feature. - void NotifyDecoderSupportKnown(base::OnceClosure callback); - - // If the current encoder support is not yet known, use this to register a - // callback that is notified once the support is known. At that point, calling - // GetVideoEncodeAcceleratorSupportedProfiles will give the set of supported - // encoder profiles. - // - // There is no way to unsubscribe a callback, it is recommended to use a - // WeakPtr if you need this feature. - void NotifyEncoderSupportKnown(base::OnceClosure callback); - - protected: - class Notifier { - public: - Notifier(); - ~Notifier(); - - void Register(base::OnceClosure callback); - void Notify(); - - bool is_notified() { return is_notified_; } - - private: - bool is_notified_ = false; - std::vector<base::OnceClosure> callbacks_; - }; - - void OnDecoderSupportFailed(); - void OnGetSupportedDecoderConfigs(); - - void OnEncoderSupportFailed(); - void OnGetVideoEncodeAcceleratorSupportedProfiles( - const media::VideoEncodeAccelerator::SupportedProfiles& - supported_profiles); - - // Task runner on the Media thread for running multi-media operations - // (e.g., creating a video decoder). - // In Fuchsia, it needs to be started with the IO message pump for FIDL calls. - scoped_refptr<base::SequencedTaskRunner> media_task_runner_; - - // Shared pointer to a shared context provider. All access should happen only - // on the media thread. - const scoped_refptr<viz::ContextProviderCommandBuffer> context_provider_; - - // Whether video acceleration encoding/decoding should be enabled. - const bool video_decode_accelerator_enabled_; - const bool video_encode_accelerator_enabled_; - - base::Lock supported_profiles_lock_; - - // If the Optional is empty, then we have not yet gotten the configs. - // If the Optional contains an empty vector, then we have gotten the result - // and there are no supported configs. - absl::optional<media::SupportedVideoDecoderConfigs> supported_decoder_configs_ - GUARDED_BY(supported_profiles_lock_); - absl::optional<media::VideoEncodeAccelerator::SupportedProfiles> - supported_vea_profiles_ GUARDED_BY(supported_profiles_lock_); - - media::VideoDecoderType video_decoder_type_ - GUARDED_BY(supported_profiles_lock_) = media::VideoDecoderType::kUnknown; - - Notifier decoder_support_notifier_ GUARDED_BY(supported_profiles_lock_); - Notifier encoder_support_notifier_ GUARDED_BY(supported_profiles_lock_); - - private: - void BindOnTaskRunner( - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote); - - mojo::Remote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_; -}; - -// CodecFactoryDefault is the default derived class, which has no -// decoder provider. It does not have any supported video decoder configs and -// returns a null pointer when creating a hardware video decoder. -class CodecFactoryDefault final : public CodecFactory { - public: - CodecFactoryDefault( - scoped_refptr<base::SequencedTaskRunner> task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote); - ~CodecFactoryDefault() override; - - // Returns nullptr since there is no decoder provider. - std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) override; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_CODEC_FACTORY_H_
diff --git a/content/renderer/media/codec_factory_fuchsia.cc b/content/renderer/media/codec_factory_fuchsia.cc deleted file mode 100644 index c8e6d2b..0000000 --- a/content/renderer/media/codec_factory_fuchsia.cc +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/codec_factory_fuchsia.h" - -#include "base/functional/bind.h" -#include "base/location.h" -#include "base/synchronization/lock.h" -#include "content/renderer/media/codec_factory.h" -#include "media/base/decoder.h" -#include "media/base/overlay_info.h" -#include "media/base/supported_video_decoder_config.h" -#include "media/base/video_decoder.h" -#include "media/fuchsia/mojom/fuchsia_media.mojom.h" -#include "media/fuchsia/video/fuchsia_video_decoder.h" -#include "media/video/gpu_video_accelerator_factories.h" - -namespace content { - -CodecFactoryFuchsia::CodecFactoryFuchsia( - scoped_refptr<base::SequencedTaskRunner> media_task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote, - mojo::PendingRemote<media::mojom::FuchsiaMediaCodecProvider> - pending_media_codec_provider_remote) - : CodecFactory(std::move(media_task_runner), - std::move(context_provider), - video_decode_accelerator_enabled, - video_encode_accelerator_enabled, - std::move(pending_vea_provider_remote)) { - media_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&CodecFactoryFuchsia::BindOnTaskRunner, - base::Unretained(this), - std::move(pending_media_codec_provider_remote))); -} -CodecFactoryFuchsia::~CodecFactoryFuchsia() = default; - -std::unique_ptr<media::VideoDecoder> CodecFactoryFuchsia::CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) { - DCHECK(video_decode_accelerator_enabled_); - - return std::make_unique<media::FuchsiaVideoDecoder>(context_provider_, - media_codec_provider_, - /*allow_overlays=*/true); -} - -void CodecFactoryFuchsia::BindOnTaskRunner( - mojo::PendingRemote<media::mojom::FuchsiaMediaCodecProvider> - media_codec_provider_remote) { - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - - if (!video_decode_accelerator_enabled_) { - OnDecoderSupportFailed(); - return; - } - - media_codec_provider_.Bind(std::move(media_codec_provider_remote), - media_task_runner_); - // The remote might be disconnected if the decoding process crashes, for - // example a decoder driver failure. Set a disconnect handler to watch these - // types of failures and treat them as if there are no supported decoder - // configs. - // Unretained is safe since CodecFactory is never destroyed. - // It lives until the process shuts down. - media_codec_provider_.set_disconnect_handler( - base::BindOnce(&CodecFactoryFuchsia::OnDecoderSupportFailed, - base::Unretained(this)), - media_task_runner_); - media_codec_provider_->GetSupportedVideoDecoderConfigs( - base::BindOnce(&CodecFactoryFuchsia::OnGetSupportedDecoderConfigs, - base::Unretained(this))); -} - -void CodecFactoryFuchsia::OnGetSupportedDecoderConfigs( - const media::SupportedVideoDecoderConfigs& supported_configs) { - { - base::AutoLock lock(supported_profiles_lock_); - supported_decoder_configs_.emplace(supported_configs); - video_decoder_type_ = media::VideoDecoderType::kFuchsia; - } - CodecFactory::OnGetSupportedDecoderConfigs(); -} - -} // namespace content
diff --git a/content/renderer/media/codec_factory_fuchsia.h b/content/renderer/media/codec_factory_fuchsia.h deleted file mode 100644 index 743c203..0000000 --- a/content/renderer/media/codec_factory_fuchsia.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_CODEC_FACTORY_FUCHSIA_H_ -#define CONTENT_RENDERER_MEDIA_CODEC_FACTORY_FUCHSIA_H_ - -#include "content/common/content_export.h" -#include "content/renderer/media/codec_factory.h" -#include "media/base/overlay_info.h" -#include "media/base/video_decoder.h" -#include "media/fuchsia/mojom/fuchsia_media.mojom.h" -#include "media/video/gpu_video_accelerator_factories.h" -#include "mojo/public/cpp/bindings/shared_remote.h" - -namespace content { - -// CodecFactoryFuchsia gets hardware decoder resources -// via media::mojom::FuchsiaMediaCodecProvider. -// -// Codec-related services on Fuchsia are used directly from the renderer process -// after the browser process provides a connection to the FIDL protocol via -// media::mojom::FuchsiaMediaCodecProvider. This can improve performance by -// avoiding the need to hop through the browser process. -class CONTENT_EXPORT CodecFactoryFuchsia final : public CodecFactory { - public: - CodecFactoryFuchsia( - scoped_refptr<base::SequencedTaskRunner> media_task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote, - mojo::PendingRemote<media::mojom::FuchsiaMediaCodecProvider> - pending_media_codec_provider_remote); - ~CodecFactoryFuchsia() override; - - std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) override; - - private: - void BindOnTaskRunner( - mojo::PendingRemote<media::mojom::FuchsiaMediaCodecProvider> - media_codec_provider_remote); - void OnGetSupportedDecoderConfigs( - const media::SupportedVideoDecoderConfigs& supported_configs); - - mojo::SharedRemote<media::mojom::FuchsiaMediaCodecProvider> - media_codec_provider_; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_CODEC_FACTORY_FUCHSIA_H_
diff --git a/content/renderer/media/codec_factory_mojo.cc b/content/renderer/media/codec_factory_mojo.cc deleted file mode 100644 index 411d3ab..0000000 --- a/content/renderer/media/codec_factory_mojo.cc +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/codec_factory_mojo.h" - -#include "base/functional/bind.h" -#include "base/location.h" -#include "base/synchronization/lock.h" -#include "content/renderer/media/codec_factory.h" -#include "media/base/overlay_info.h" -#include "media/mojo/clients/mojo_video_decoder.h" -#include "media/mojo/mojom/interface_factory.mojom.h" -#include "media/video/gpu_video_accelerator_factories.h" -#include "mojo/public/cpp/bindings/pending_remote.h" - -namespace content { - -CodecFactoryMojo::CodecFactoryMojo( - scoped_refptr<base::SequencedTaskRunner> media_task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote, - mojo::PendingRemote<media::mojom::InterfaceFactory> - pending_interface_factory_remote) - : CodecFactory(std::move(media_task_runner), - std::move(context_provider), - video_decode_accelerator_enabled, - video_encode_accelerator_enabled, - std::move(pending_vea_provider_remote)) { - media_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&CodecFactoryMojo::BindOnTaskRunner, - base::Unretained(this), - std::move(pending_interface_factory_remote))); -} -CodecFactoryMojo::~CodecFactoryMojo() = default; - -std::unique_ptr<media::VideoDecoder> CodecFactoryMojo::CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) { - DCHECK(video_decode_accelerator_enabled_); - DCHECK(interface_factory_.is_bound()); - - mojo::PendingRemote<media::mojom::VideoDecoder> video_decoder; - interface_factory_->CreateVideoDecoder( - video_decoder.InitWithNewPipeAndPassReceiver(), /*dst_video_decoder=*/{}); - return std::make_unique<media::MojoVideoDecoder>( - media_task_runner_, gpu_factories, media_log, std::move(video_decoder), - std::move(request_overlay_info_cb), rendering_color_space); -} - -void CodecFactoryMojo::BindOnTaskRunner( - mojo::PendingRemote<media::mojom::InterfaceFactory> - interface_factory_remote) { - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(context_provider_); - - interface_factory_.Bind(std::move(interface_factory_remote)); - - if (!video_decode_accelerator_enabled_) { - OnDecoderSupportFailed(); - return; - } - - // Note: This is a bit of a hack, since we don't specify the implementation - // before asking for the map of supported configs. We do this because it - // (a) saves an ipc call, and (b) makes the return of those configs atomic. - interface_factory_->CreateVideoDecoder( - video_decoder_.BindNewPipeAndPassReceiver(), /*dst_video_decoder=*/{}); - // The remote might be disconnected if the decoding process crashes, for - // example a GPU driver failure. Set a disconnect handler to watch these - // types of failures and treat them as if there are no supported decoder - // configs. - // Unretained is safe since CodecFactory is never destroyed. - // It lives until the process shuts down. - video_decoder_.set_disconnect_handler(base::BindOnce( - &CodecFactoryMojo::OnDecoderSupportFailed, base::Unretained(this))); - video_decoder_->GetSupportedConfigs(base::BindOnce( - &CodecFactoryMojo::OnGetSupportedDecoderConfigs, base::Unretained(this))); -} - -void CodecFactoryMojo::OnGetSupportedDecoderConfigs( - const media::SupportedVideoDecoderConfigs& supported_configs, - media::VideoDecoderType decoder_type) { - { - base::AutoLock lock(supported_profiles_lock_); - video_decoder_.reset(); - supported_decoder_configs_.emplace(supported_configs); - video_decoder_type_ = decoder_type; - } - CodecFactory::OnGetSupportedDecoderConfigs(); -} - -} // namespace content
diff --git a/content/renderer/media/codec_factory_mojo.h b/content/renderer/media/codec_factory_mojo.h deleted file mode 100644 index ff371a6..0000000 --- a/content/renderer/media/codec_factory_mojo.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_MEDIA_CODEC_FACTORY_MOJO_H_ -#define CONTENT_RENDERER_MEDIA_CODEC_FACTORY_MOJO_H_ - -#include <memory> - -#include "content/common/content_export.h" -#include "content/renderer/media/codec_factory.h" -#include "media/base/decoder.h" -#include "media/base/overlay_info.h" -#include "media/base/video_decoder.h" -#include "media/mojo/mojom/interface_factory.mojom.h" -#include "media/video/gpu_video_accelerator_factories.h" -#include "mojo/public/cpp/bindings/remote.h" - -namespace content { - -// CodecFactoryMojo gets hardware decoder resources -// via media::mojom::InterfaceFactory. Use it when mojo-based video decoder is -// enabled. -class CONTENT_EXPORT CodecFactoryMojo final : public CodecFactory { - public: - CodecFactoryMojo( - scoped_refptr<base::SequencedTaskRunner> media_task_runner, - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool video_decode_accelerator_enabled, - bool video_encode_accelerator_enabled, - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - pending_vea_provider_remote, - mojo::PendingRemote<media::mojom::InterfaceFactory> - pending_interface_factory_remote); - ~CodecFactoryMojo() override; - - std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( - media::GpuVideoAcceleratorFactories* gpu_factories, - media::MediaLog* media_log, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& rendering_color_space) override; - - private: - void BindOnTaskRunner( - mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory); - void OnGetSupportedDecoderConfigs( - const media::SupportedVideoDecoderConfigs& supported_configs, - media::VideoDecoderType decoder_type); - - mojo::Remote<media::mojom::InterfaceFactory> interface_factory_; - mojo::Remote<media::mojom::VideoDecoder> video_decoder_; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_MEDIA_CODEC_FACTORY_MOJO_H_
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index c6022f1..d2bfea3 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -6,10 +6,8 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> -#include <memory> -#include <optional> -#include "base/functional/bind.h" +#include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/memory/unsafe_shared_memory_region.h" #include "base/metrics/histogram_macros.h" @@ -17,15 +15,22 @@ #include "base/unguessable_token.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" -#include "content/renderer/media/codec_factory.h" +#include "components/viz/common/gpu/context_provider.h" +#include "content/child/child_thread_impl.h" +#include "content/public/common/content_features.h" #include "content/renderer/render_thread_impl.h" +#include "gpu/command_buffer/client/context_support.h" +#include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "gpu/ipc/client/command_buffer_proxy_impl.h" #include "gpu/ipc/client/gpu_channel_host.h" -#include "media/base/decoder.h" -#include "media/base/supported_video_decoder_config.h" +#include "gpu/ipc/common/gpu_memory_buffer_support.h" +#include "media/base/bind_to_current_loop.h" +#include "media/gpu/gpu_video_accelerator_util.h" #include "media/mojo/buildflags.h" +#include "media/mojo/clients/mojo_video_decoder.h" +#include "media/mojo/clients/mojo_video_encode_accelerator.h" #include "media/video/video_encode_accelerator.h" #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h" #include "third_party/skia/include/core/SkTypes.h" @@ -48,6 +53,26 @@ } // namespace +GpuVideoAcceleratorFactoriesImpl::Notifier::Notifier() = default; +GpuVideoAcceleratorFactoriesImpl::Notifier::~Notifier() = default; + +void GpuVideoAcceleratorFactoriesImpl::Notifier::Register( + base::OnceClosure callback) { + if (is_notified_) { + std::move(callback).Run(); + return; + } + callbacks_.push_back(std::move(callback)); +} + +void GpuVideoAcceleratorFactoriesImpl::Notifier::Notify() { + DCHECK(!is_notified_); + is_notified_ = true; + for (auto& callback : callbacks_) + std::move(callback).Run(); + callbacks_.clear(); +} + // static std::unique_ptr<GpuVideoAcceleratorFactoriesImpl> GpuVideoAcceleratorFactoriesImpl::Create( @@ -55,40 +80,22 @@ const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, - std::unique_ptr<CodecFactory> codec_factory, bool enable_video_gpu_memory_buffers, bool enable_media_stream_gpu_memory_buffers, bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator) { + bool enable_video_encode_accelerator, + mojo::PendingRemote<media::mojom::InterfaceFactory> + interface_factory_remote, + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_remote) { RecordContextProviderPhaseUmaEnum( ContextProviderPhase::CONTEXT_PROVIDER_ACQUIRED); return base::WrapUnique(new GpuVideoAcceleratorFactoriesImpl( std::move(gpu_channel_host), main_thread_task_runner, task_runner, - std::move(context_provider), std::move(codec_factory), - RenderThreadImpl::current()->GetGpuMemoryBufferManager(), - enable_video_gpu_memory_buffers, enable_media_stream_gpu_memory_buffers, - enable_video_decode_accelerator, enable_video_encode_accelerator)); -} - -// static -std::unique_ptr<GpuVideoAcceleratorFactoriesImpl> -GpuVideoAcceleratorFactoriesImpl::CreateForTesting( - scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, - const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner, - const scoped_refptr<base::SequencedTaskRunner>& task_runner, - const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, - std::unique_ptr<CodecFactory> codec_factory, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - bool enable_video_gpu_memory_buffers, - bool enable_media_stream_gpu_memory_buffers, - bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator) { - return base::WrapUnique(new GpuVideoAcceleratorFactoriesImpl( - std::move(gpu_channel_host), main_thread_task_runner, task_runner, - std::move(context_provider), std::move(codec_factory), - std::move(gpu_memory_buffer_manager), enable_video_gpu_memory_buffers, + context_provider, enable_video_gpu_memory_buffers, enable_media_stream_gpu_memory_buffers, enable_video_decode_accelerator, - enable_video_encode_accelerator)); + enable_video_encode_accelerator, std::move(interface_factory_remote), + std::move(vea_provider_remote))); } GpuVideoAcceleratorFactoriesImpl::GpuVideoAcceleratorFactoriesImpl( @@ -96,40 +103,53 @@ const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, - std::unique_ptr<CodecFactory> codec_factory, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, bool enable_video_gpu_memory_buffers, bool enable_media_stream_gpu_memory_buffers, bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator) + bool enable_video_encode_accelerator, + mojo::PendingRemote<media::mojom::InterfaceFactory> + interface_factory_remote, + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_remote) : main_thread_task_runner_(main_thread_task_runner), task_runner_(task_runner), gpu_channel_host_(std::move(gpu_channel_host)), - codec_factory_(std::move(codec_factory)), context_provider_(context_provider), enable_video_gpu_memory_buffers_(enable_video_gpu_memory_buffers), enable_media_stream_gpu_memory_buffers_( enable_media_stream_gpu_memory_buffers), video_decode_accelerator_enabled_(enable_video_decode_accelerator), video_encode_accelerator_enabled_(enable_video_encode_accelerator), - gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { + gpu_memory_buffer_manager_( + RenderThreadImpl::current()->GetGpuMemoryBufferManager()) { DCHECK(main_thread_task_runner_); DCHECK(gpu_channel_host_); task_runner_->PostTask( FROM_HERE, base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner, - base::Unretained(this))); + base::Unretained(this), + std::move(interface_factory_remote), + std::move(vea_provider_remote))); } GpuVideoAcceleratorFactoriesImpl::~GpuVideoAcceleratorFactoriesImpl() {} -void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner() { +void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner( + mojo::PendingRemote<media::mojom::InterfaceFactory> + interface_factory_remote, + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_remote) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(context_provider_); + interface_factory_.Bind(std::move(interface_factory_remote)); + vea_provider_.Bind(std::move(vea_provider_remote)); + if (context_provider_->BindToCurrentSequence() != gpu::ContextResult::kSuccess) { + OnDecoderSupportFailed(); + OnEncoderSupportFailed(); OnContextLost(); return; } @@ -140,24 +160,98 @@ context_provider_->GetCommandBufferProxy()->GetGpuChannel().GetChannelToken( base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::OnChannelTokenReady, base::Unretained(this))); + + if (video_encode_accelerator_enabled_) { + vea_provider_.set_disconnect_handler(base::BindOnce( + &GpuVideoAcceleratorFactoriesImpl::OnEncoderSupportFailed, + base::Unretained(this))); + vea_provider_->GetVideoEncodeAcceleratorSupportedProfiles( + base::BindOnce(&GpuVideoAcceleratorFactoriesImpl:: + OnGetVideoEncodeAcceleratorSupportedProfiles, + base::Unretained(this))); + } else { + OnEncoderSupportFailed(); + } + +#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) + if (video_decode_accelerator_enabled_) { + // Note: This is a bit of a hack, since we don't specify the implementation + // before asking for the map of supported configs. We do this because it + // (a) saves an ipc call, and (b) makes the return of those configs atomic. + interface_factory_->CreateVideoDecoder( + video_decoder_.BindNewPipeAndPassReceiver(), /*dst_video_decoder=*/{}); + video_decoder_.set_disconnect_handler(base::BindOnce( + &GpuVideoAcceleratorFactoriesImpl::OnDecoderSupportFailed, + base::Unretained(this))); + video_decoder_->GetSupportedConfigs(base::BindOnce( + &GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs, + base::Unretained(this))); + } else { + OnDecoderSupportFailed(); + } +#else + OnDecoderSupportFailed(); +#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) } bool GpuVideoAcceleratorFactoriesImpl::IsDecoderSupportKnown() { - return codec_factory_->IsDecoderSupportKnown(); + base::AutoLock lock(supported_profiles_lock_); + return decoder_support_notifier_.is_notified(); } void GpuVideoAcceleratorFactoriesImpl::NotifyDecoderSupportKnown( base::OnceClosure callback) { - codec_factory_->NotifyDecoderSupportKnown(std::move(callback)); + base::AutoLock lock(supported_profiles_lock_); + decoder_support_notifier_.Register( + media::BindToCurrentLoop(std::move(callback))); +} + +void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs( + const media::SupportedVideoDecoderConfigs& supported_configs, + media::VideoDecoderType decoder_type) { + base::AutoLock lock(supported_profiles_lock_); + video_decoder_.reset(); + supported_decoder_configs_ = supported_configs; + video_decoder_type_ = decoder_type; + decoder_support_notifier_.Notify(); +} + +void GpuVideoAcceleratorFactoriesImpl::OnDecoderSupportFailed() { + base::AutoLock lock(supported_profiles_lock_); + video_decoder_.reset(); + if (decoder_support_notifier_.is_notified()) + return; + supported_decoder_configs_ = media::SupportedVideoDecoderConfigs(); + decoder_support_notifier_.Notify(); } bool GpuVideoAcceleratorFactoriesImpl::IsEncoderSupportKnown() { - return codec_factory_->IsEncoderSupportKnown(); + base::AutoLock lock(supported_profiles_lock_); + return encoder_support_notifier_.is_notified(); } void GpuVideoAcceleratorFactoriesImpl::NotifyEncoderSupportKnown( base::OnceClosure callback) { - codec_factory_->NotifyEncoderSupportKnown(std::move(callback)); + base::AutoLock lock(supported_profiles_lock_); + encoder_support_notifier_.Register( + media::BindToCurrentLoop(std::move(callback))); +} + +void GpuVideoAcceleratorFactoriesImpl:: + OnGetVideoEncodeAcceleratorSupportedProfiles( + const media::VideoEncodeAccelerator::SupportedProfiles& + supported_profiles) { + base::AutoLock lock(supported_profiles_lock_); + supported_vea_profiles_ = supported_profiles; + encoder_support_notifier_.Notify(); +} + +void GpuVideoAcceleratorFactoriesImpl::OnEncoderSupportFailed() { + base::AutoLock lock(supported_profiles_lock_); + if (encoder_support_notifier_.is_notified()) + return; + supported_vea_profiles_ = media::VideoEncodeAccelerator::SupportedProfiles(); + encoder_support_notifier_.Notify(); } bool GpuVideoAcceleratorFactoriesImpl::CheckContextLost() { @@ -236,14 +330,16 @@ return Supported::kFalse; } - auto supported_decoder_configs = - codec_factory_->GetSupportedVideoDecoderConfigs(); - if (!supported_decoder_configs) { + base::AutoLock lock(supported_profiles_lock_); + + // If GetSupportedConfigs() has not completed (or was never started), report + // that all configs are supported. Clients will find out that configs are not + // supported when VideoDecoder::Initialize() fails. + if (!supported_decoder_configs_) return Supported::kUnknown; - } // Iterate over the supported configs. - for (const auto& supported : *supported_decoder_configs) { + for (const auto& supported : *supported_decoder_configs_) { if (supported.Matches(config)) return Supported::kTrue; } @@ -251,7 +347,8 @@ } media::VideoDecoderType GpuVideoAcceleratorFactoriesImpl::GetDecoderType() { - return codec_factory_->GetVideoDecoderType(); + base::AutoLock lock(supported_profiles_lock_); + return video_decoder_type_; } std::unique_ptr<media::VideoDecoder> @@ -260,21 +357,50 @@ media::RequestOverlayInfoCB request_overlay_info_cb) { DCHECK(video_decode_accelerator_enabled_); DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(interface_factory_.is_bound()); + +#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) if (CheckContextLost()) return nullptr; - return codec_factory_->CreateVideoDecoder( - this, media_log, request_overlay_info_cb, rendering_color_space_); + mojo::PendingRemote<media::mojom::VideoDecoder> video_decoder; + interface_factory_->CreateVideoDecoder( + video_decoder.InitWithNewPipeAndPassReceiver(), /*dst_video_decoder=*/{}); + return std::make_unique<media::MojoVideoDecoder>( + task_runner_, this, media_log, std::move(video_decoder), + std::move(request_overlay_info_cb), rendering_color_space_); +#else + return nullptr; +#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) } std::unique_ptr<media::VideoEncodeAccelerator> GpuVideoAcceleratorFactoriesImpl::CreateVideoEncodeAccelerator() { DCHECK(video_encode_accelerator_enabled_); DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(vea_provider_.is_bound()); if (CheckContextLost()) return nullptr; - return codec_factory_->CreateVideoEncodeAccelerator(); + base::AutoLock lock(supported_profiles_lock_); + // When |supported_vea_profiles_| is empty, no hw encoder is available or + // we have not yet gotten the supported profiles. + if (!supported_vea_profiles_) { + DVLOG(2) << "VEA's profiles have not yet been gotten"; + } else if (supported_vea_profiles_->empty()) { + // There is no profile supported by VEA. + return nullptr; + } + + mojo::PendingRemote<media::mojom::VideoEncodeAccelerator> vea; + vea_provider_->CreateVideoEncodeAccelerator( + vea.InitWithNewPipeAndPassReceiver()); + + if (!vea) + return nullptr; + + return std::unique_ptr<media::VideoEncodeAccelerator>( + new media::MojoVideoEncodeAccelerator(std::move(vea))); } std::unique_ptr<gfx::GpuMemoryBuffer> @@ -396,7 +522,8 @@ absl::optional<media::VideoEncodeAccelerator::SupportedProfiles> GpuVideoAcceleratorFactoriesImpl::GetVideoEncodeAcceleratorSupportedProfiles() { - return codec_factory_->GetVideoEncodeAcceleratorSupportedProfiles(); + base::AutoLock lock(supported_profiles_lock_); + return supported_vea_profiles_; } viz::RasterContextProvider*
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h index bf8aa6e..99bd984 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -12,19 +12,20 @@ #include <vector> #include "base/callback_list.h" -#include "base/memory/scoped_refptr.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "base/synchronization/waitable_event.h" #include "base/unguessable_token.h" -#include "build/build_config.h" #include "components/viz/common/gpu/context_lost_observer.h" -#include "content/common/content_export.h" -#include "content/renderer/media/codec_factory.h" -#include "media/mojo/buildflags.h" +#include "media/base/supported_video_decoder_config.h" +#include "media/mojo/mojom/interface_factory.mojom.h" +#include "media/mojo/mojom/video_decoder.mojom.h" +#include "media/mojo/mojom/video_encode_accelerator.mojom.h" #include "media/video/gpu_video_accelerator_factories.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" - -#if BUILDFLAG(IS_FUCHSIA) -#include <fuchsia/mediacodec/cpp/fidl.h> -#endif +#include "ui/gfx/geometry/size.h" namespace base { class SequencedTaskRunner; @@ -51,7 +52,7 @@ // the |task_runner_|, as provided during construction. // |context_provider| should not support locking and will be bound to // |task_runner_| where all the operations on the context should also happen. -class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl +class GpuVideoAcceleratorFactoriesImpl : public media::GpuVideoAcceleratorFactories, public viz::ContextLostObserver { public: @@ -62,22 +63,14 @@ const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, - std::unique_ptr<CodecFactory> codec_factory, bool enable_video_gpu_memory_buffers, bool enable_media_stream_gpu_memory_buffers, bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator); - static std::unique_ptr<GpuVideoAcceleratorFactoriesImpl> CreateForTesting( - scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, - const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner, - const scoped_refptr<base::SequencedTaskRunner>& task_runner, - const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, - std::unique_ptr<CodecFactory> codec_factory, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - bool enable_video_gpu_memory_buffers, - bool enable_media_stream_gpu_memory_buffers, - bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator); + bool enable_video_encode_accelerator, + mojo::PendingRemote<media::mojom::InterfaceFactory> + interface_factory_remote, + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_remote); // media::GpuVideoAcceleratorFactories implementation. bool IsGpuVideoDecodeAcceleratorEnabled() override; @@ -147,32 +140,60 @@ ~GpuVideoAcceleratorFactoriesImpl() override; private: + class Notifier { + public: + Notifier(); + ~Notifier(); + + void Register(base::OnceClosure callback); + void Notify(); + + bool is_notified() { return is_notified_; } + + private: + bool is_notified_ = false; + std::vector<base::OnceClosure> callbacks_; + }; + GpuVideoAcceleratorFactoriesImpl( scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner, const scoped_refptr<base::SequencedTaskRunner>& task_runner, const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, - std::unique_ptr<CodecFactory> codec_factory, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, bool enable_gpu_memory_buffer_video_frames_for_video, bool enable_gpu_memory_buffer_video_frames_for_media_stream, bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator); + bool enable_video_encode_accelerator, + mojo::PendingRemote<media::mojom::InterfaceFactory> + interface_factory_remote, + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_remote); - void BindOnTaskRunner(); + void BindOnTaskRunner( + mojo::PendingRemote<media::mojom::InterfaceFactory> + interface_factory_remote, + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider_remote); // viz::ContextLostObserver implementation. void OnContextLost() override; void SetContextProviderLostOnMainThread(); + void OnSupportedDecoderConfigs( + const media::SupportedVideoDecoderConfigs& supported_configs, + media::VideoDecoderType decoder_type); + void OnDecoderSupportFailed(); + + void OnGetVideoEncodeAcceleratorSupportedProfiles( + const media::VideoEncodeAccelerator::SupportedProfiles& + supported_profiles); + void OnEncoderSupportFailed(); void OnChannelTokenReady(const base::UnguessableToken& token); const scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner_; const scoped_refptr<base::SequencedTaskRunner> task_runner_; const scoped_refptr<gpu::GpuChannelHost> gpu_channel_host_; - const std::unique_ptr<CodecFactory> codec_factory_; - // Shared pointer to a shared context provider. It is initially set on main // thread, but all subsequent access and destruction should happen only on the // media thread. @@ -197,6 +218,27 @@ gfx::ColorSpace rendering_color_space_; gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_; + + mojo::Remote<media::mojom::InterfaceFactory> interface_factory_; + mojo::Remote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_; + + // SupportedDecoderConfigs state. + mojo::Remote<media::mojom::VideoDecoder> video_decoder_; + + base::Lock supported_profiles_lock_; + + // If the Optional is empty, then we have not yet gotten the configs. If the + // Optional contains an empty vector, then we have gotten the result and there + // are no supported configs. + absl::optional<media::SupportedVideoDecoderConfigs> supported_decoder_configs_ + GUARDED_BY(supported_profiles_lock_); + media::VideoDecoderType video_decoder_type_ + GUARDED_BY(supported_profiles_lock_) = media::VideoDecoderType::kUnknown; + Notifier decoder_support_notifier_ GUARDED_BY(supported_profiles_lock_); + + absl::optional<media::VideoEncodeAccelerator::SupportedProfiles> + supported_vea_profiles_ GUARDED_BY(supported_profiles_lock_); + Notifier encoder_support_notifier_ GUARDED_BY(supported_profiles_lock_); }; } // namespace content
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl_unittest.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl_unittest.cc deleted file mode 100644 index 5b70f84..0000000 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl_unittest.cc +++ /dev/null
@@ -1,685 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h" - -#include <GLES2/gl2.h> -#include <cstddef> -#include <memory> - -#include "base/memory/scoped_refptr.h" -#include "base/test/gtest_util.h" -#include "base/test/task_environment.h" -#include "base/test/test_future.h" -#include "build/build_config.h" -#include "components/viz/common/gpu/context_cache_controller.h" -#include "components/viz/common/gpu/context_lost_observer.h" -#include "components/viz/test/test_gpu_memory_buffer_manager.h" -#include "content/public/common/gpu_stream_constants.h" -#include "content/renderer/media/codec_factory.h" -#include "gpu/command_buffer/client/gles2_interface_stub.h" -#include "gpu/command_buffer/common/capabilities.h" -#include "gpu/command_buffer/common/context_creation_attribs.h" -#include "gpu/command_buffer/common/context_result.h" -#include "gpu/config/gpu_feature_info.h" -#include "gpu/ipc/client/command_buffer_proxy_impl.h" -#include "gpu/ipc/client/gpu_channel_host.h" -#include "gpu/ipc/common/gpu_channel.mojom.h" -#include "gpu/ipc/common/mock_gpu_channel.h" -#include "media/base/decoder.h" -#include "media/base/media_util.h" -#include "media/base/supported_video_decoder_config.h" -#include "media/base/video_codecs.h" -#include "media/base/video_decoder_config.h" -#include "media/mojo/buildflags.h" -#include "media/mojo/mojom/video_encode_accelerator.mojom.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest-death-test.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkImage.h" - -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) -#include "content/renderer/media/codec_factory_mojo.h" -#include "media/filters/fake_video_decoder.h" -#include "media/mojo/mojom/interface_factory.mojom.h" -#include "media/mojo/services/mojo_cdm_service_context.h" -#include "media/mojo/services/mojo_media_client.h" -#include "media/mojo/services/mojo_video_decoder_service.h" -#include "mojo/public/cpp/bindings/unique_receiver_set.h" -#endif - -#if BUILDFLAG(IS_FUCHSIA) -#include "content/renderer/media/codec_factory_fuchsia.h" -#include "media/fuchsia/mojom/fuchsia_media.mojom.h" -#endif - -using ::testing::_; -using ::testing::Invoke; -using ::testing::NiceMock; -using ::testing::Return; - -namespace content { - -namespace { - -constexpr gfx::Size kCodedSize(320, 240); -constexpr gfx::Rect kVisibleRect(320, 240); -constexpr gfx::Size kNaturalSize(320, 240); - -const media::SupportedVideoDecoderConfig kH264MaxSupportedVideoDecoderConfig = - media::SupportedVideoDecoderConfig( - media::VideoCodecProfile::H264PROFILE_MIN, - media::VideoCodecProfile::H264PROFILE_MAX, - media::kDefaultSwDecodeSizeMin, - media::kDefaultSwDecodeSizeMax, - true, - false); - -const media::VideoDecoderConfig kH264BaseConfig( - media::VideoCodec::kH264, - media::H264PROFILE_MIN, - media::VideoDecoderConfig::AlphaMode::kIsOpaque, - media::VideoColorSpace(), - media::kNoTransformation, - kCodedSize, - kVisibleRect, - kNaturalSize, - media::EmptyExtraData(), - media::EncryptionScheme::kUnencrypted); - -const media::VideoDecoderConfig kVP9BaseConfig( - media::VideoCodec::kVP9, - media::VP9PROFILE_MIN, - media::VideoDecoderConfig::AlphaMode::kIsOpaque, - media::VideoColorSpace(), - media::kNoTransformation, - kCodedSize, - kVisibleRect, - kNaturalSize, - media::EmptyExtraData(), - media::EncryptionScheme::kUnencrypted); - -} // namespace - -class TestGpuChannelHost : public gpu::GpuChannelHost { - public: - explicit TestGpuChannelHost(gpu::mojom::GpuChannel& gpu_channel) - : GpuChannelHost(0 /* channel_id */, - gpu::GPUInfo(), - gpu::GpuFeatureInfo(), - mojo::ScopedMessagePipeHandle( - mojo::MessagePipeHandle(mojo::kInvalidHandleValue))), - gpu_channel_(gpu_channel) {} - - gpu::mojom::GpuChannel& GetGpuChannel() override { return *gpu_channel_; } - - protected: - ~TestGpuChannelHost() override = default; - const raw_ref<gpu::mojom::GpuChannel> gpu_channel_; -}; - -class MockOverlayInfoCbHandler { - public: - MOCK_METHOD2(Call, void(bool, media::ProvideOverlayInfoCB)); -}; - -class MockContextProviderCommandBuffer - : public viz::ContextProviderCommandBuffer { - public: - MockContextProviderCommandBuffer( - scoped_refptr<gpu::GpuChannelHost> channel, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) - : viz::ContextProviderCommandBuffer( - std::move(channel), - gpu_memory_buffer_manager, - content::kGpuStreamIdDefault, - content::kGpuStreamPriorityDefault, - gpu::kNullSurfaceHandle, - GURL(), - false, - false, - true, - gpu::SharedMemoryLimits(), - gpu::ContextCreationAttribs(), - viz::command_buffer_metrics::ContextType::FOR_TESTING) {} - - MOCK_METHOD(gpu::CommandBufferProxyImpl*, - GetCommandBufferProxy, - (), - (override)); - - // ContextProvider / RasterContextProvider implementation. - MOCK_METHOD(gpu::ContextResult, BindToCurrentSequence, (), (override)); - MOCK_METHOD(gpu::gles2::GLES2Interface*, ContextGL, (), (override)); - MOCK_METHOD(gpu::raster::RasterInterface*, RasterInterface, (), (override)); - MOCK_METHOD(gpu::ContextSupport*, ContextSupport, (), (override)); - MOCK_METHOD(class GrDirectContext*, GrContext, (), (override)); - MOCK_METHOD(gpu::SharedImageInterface*, SharedImageInterface, (), (override)); - MOCK_METHOD(viz::ContextCacheController*, CacheController, (), (override)); - MOCK_METHOD(base::Lock*, GetLock, (), (override)); - MOCK_METHOD(gpu::Capabilities&, ContextCapabilities, (), (const, override)); - MOCK_METHOD(gpu::GpuFeatureInfo&, GetGpuFeatureInfo, (), (const, override)); - MOCK_METHOD(void, AddObserver, (viz::ContextLostObserver*), (override)); - MOCK_METHOD(void, RemoveObserver, (viz::ContextLostObserver*), (override)); - - // base::trace_event::MemoryDumpProvider implementation. - MOCK_METHOD(bool, - OnMemoryDump, - (const base::trace_event::MemoryDumpArgs&, - base::trace_event::ProcessMemoryDump*), - (override)); - - protected: - ~MockContextProviderCommandBuffer() override = default; -}; - -class MockGLESInterface : public gpu::gles2::GLES2InterfaceStub { - public: - MOCK_METHOD(GLenum, GetGraphicsResetStatusKHR, ()); -}; - -class FakeVEAProviderImpl - : public media::mojom::VideoEncodeAcceleratorProvider { - public: - ~FakeVEAProviderImpl() override = default; - - void Bind(mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> - receiver) { - receiver_.Bind(std::move(receiver)); - } - - void SetVideoEncodeAcceleratorSupportedProfiles( - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - supported_profile) { - supported_profile_ = supported_profile; - } - // media::mojom::VideoEncodeAcceleratorProvider impl. - void CreateVideoEncodeAccelerator( - mojo::PendingReceiver<media::mojom::VideoEncodeAccelerator> receiver) - override {} - void GetVideoEncodeAcceleratorSupportedProfiles( - GetVideoEncodeAcceleratorSupportedProfilesCallback callback) override { - std::move(callback).Run(supported_profile_); - } - - private: - mojo::Receiver<media::mojom::VideoEncodeAcceleratorProvider> receiver_{this}; - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - supported_profile_; -}; - -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) -// Client to MojoVideoDecoderService vended by FakeInterfaceFactory. Creates a -// FakeGpuVideoDecoder when requested. -class FakeMojoMediaClient : public media::MojoMediaClient { - public: - void SetSupportedVideoDecoderConfigs( - media::SupportedVideoDecoderConfigs configs) { - supported_video_decoder_configs_ = configs; - } - - // MojoMediaClient implementation. - std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - media::MediaLog* media_log, - media::mojom::CommandBufferIdPtr command_buffer_id, - media::RequestOverlayInfoCB request_overlay_info_cb, - const gfx::ColorSpace& target_color_space, - mojo::PendingRemote<media::stable::mojom::StableVideoDecoder> - oop_video_decoder) override { - return std::make_unique<media::FakeVideoDecoder>( - 0 /* decoder_id */, 0 /* decoding_delay */, - 13 /* max_parallel_decoding_requests */, media::BytesDecodedCB()); - } - media::SupportedVideoDecoderConfigs GetSupportedVideoDecoderConfigs() - override { - return supported_video_decoder_configs_; - } - media::VideoDecoderType GetDecoderImplementationType() override { - return media::VideoDecoderType::kTesting; - } - - private: - media::SupportedVideoDecoderConfigs supported_video_decoder_configs_; -}; - -// Other end of remote InterfaceFactory requested by VideoDecoderBroker. Used -// to create our (fake) media::mojom::VideoDecoder. -class FakeInterfaceFactory : public media::mojom::InterfaceFactory { - public: - FakeInterfaceFactory() = default; - ~FakeInterfaceFactory() override = default; - - void Bind(mojo::PendingReceiver<media::mojom::InterfaceFactory> receiver) { - receiver_.Bind(std::move(receiver)); - receiver_.set_disconnect_handler(base::BindOnce( - &FakeInterfaceFactory::OnConnectionError, base::Unretained(this))); - } - - void SetSupportedVideoDecoderConfigs( - media::SupportedVideoDecoderConfigs configs) { - mojo_media_client_.SetSupportedVideoDecoderConfigs(configs); - } - - // Implement this one interface from mojom::InterfaceFactory. Using the real - // MojoVideoDecoderService allows us to reuse buffer conversion code. The - // FakeMojoMediaClient will create a FakeGpuVideoDecoder. - void CreateVideoDecoder( - mojo::PendingReceiver<media::mojom::VideoDecoder> receiver, - mojo::PendingRemote<media::stable::mojom::StableVideoDecoder> - dst_video_decoder) override { - video_decoder_receivers_.Add( - std::make_unique<media::MojoVideoDecoderService>( - &mojo_media_client_, &cdm_service_context_, - mojo::PendingRemote<media::stable::mojom::StableVideoDecoder>()), - std::move(receiver)); - } - - // Stub out other mojom::InterfaceFactory interfaces. - void CreateAudioDecoder( - mojo::PendingReceiver<media::mojom::AudioDecoder> receiver) override {} - void CreateAudioEncoder( - mojo::PendingReceiver<media::mojom::AudioEncoder> receiver) override {} - void CreateDefaultRenderer( - const std::string& audio_device_id, - mojo::PendingReceiver<media::mojom::Renderer> receiver) override {} -#if BUILDFLAG(ENABLE_CAST_RENDERER) - void CreateCastRenderer( - const base::UnguessableToken& overlay_plane_id, - mojo::PendingReceiver<media::mojom::Renderer> receiver) override {} -#endif -#if BUILDFLAG(IS_ANDROID) - void CreateFlingingRenderer( - const std::string& presentation_id, - mojo::PendingRemote<media::mojom::FlingingRendererClientExtension> - client_extension, - mojo::PendingReceiver<media::mojom::Renderer> receiver) override {} - void CreateMediaPlayerRenderer( - mojo::PendingRemote<media::mojom::MediaPlayerRendererClientExtension> - client_extension_remote, - mojo::PendingReceiver<media::mojom::Renderer> receiver, - mojo::PendingReceiver<media::mojom::MediaPlayerRendererExtension> - renderer_extension_receiver) override {} -#endif // BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(IS_WIN) - void CreateMediaFoundationRenderer( - mojo::PendingRemote<media::mojom::MediaLog> media_log_remote, - mojo::PendingReceiver<media::mojom::Renderer> receiver, - mojo::PendingReceiver<media::mojom::MediaFoundationRendererExtension> - renderer_extension_receiver, - mojo::PendingRemote<media::mojom::MediaFoundationRendererClientExtension> - client_extension_remote) override {} -#endif // BUILDFLAG(IS_WIN) - void CreateCdm(const media::CdmConfig& cdm_config, - CreateCdmCallback callback) override {} - - private: - void OnConnectionError() { receiver_.reset(); } - - media::MojoCdmServiceContext cdm_service_context_; - FakeMojoMediaClient mojo_media_client_; - mojo::Receiver<media::mojom::InterfaceFactory> receiver_{this}; - mojo::UniqueReceiverSet<media::mojom::VideoDecoder> video_decoder_receivers_; -}; -#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) - -#if BUILDFLAG(IS_FUCHSIA) -class FakeFuchsiaMediaCodecProvide - : public media::mojom::FuchsiaMediaCodecProvider { - public: - ~FakeFuchsiaMediaCodecProvide() override = default; - - void Bind( - mojo::PendingReceiver<media::mojom::FuchsiaMediaCodecProvider> receiver) { - receiver_.Bind(std::move(receiver)); - } - - void SetSupportedVideoDecoderConfigs( - media::SupportedVideoDecoderConfigs configs) { - supported_video_decoder_configs_ = configs; - } - - // media::mojom::FuchsiaMediaCodecProvider implementation. - void CreateVideoDecoder( - media::VideoCodec codec, - media::mojom::VideoDecoderSecureMemoryMode secure_mode, - fidl::InterfaceRequest<fuchsia::media::StreamProcessor> - stream_processor_request) final { - ADD_FAILURE() << "Not implemented."; - } - - void GetSupportedVideoDecoderConfigs( - GetSupportedVideoDecoderConfigsCallback callback) final { - std::move(callback).Run(supported_video_decoder_configs_); - } - - private: - media::SupportedVideoDecoderConfigs supported_video_decoder_configs_; - mojo::Receiver<media::mojom::FuchsiaMediaCodecProvider> receiver_{this}; -}; -#endif // BUILDFLAG(IS_FUCHSIA) - -class GpuVideoAcceleratorFactoriesImplTest : public testing::Test { - public: - GpuVideoAcceleratorFactoriesImplTest() - : gpu_channel_host_( - base::MakeRefCounted<TestGpuChannelHost>(mock_gpu_channel_)), - mock_context_provider_( - base::MakeRefCounted<NiceMock<MockContextProviderCommandBuffer>>( - gpu_channel_host_, - &gpu_memory_buffer_manager_)) {} - ~GpuVideoAcceleratorFactoriesImplTest() override = default; - - void SetUp() override { - MockGpuChannel(); - MockContextProvider(); - } - - void TearDown() override { - task_environment_.RunUntilIdle(); - ASSERT_TRUE(testing::Mock::VerifyAndClear(&mock_context_provider_)); - ASSERT_TRUE(testing::Mock::VerifyAndClear(&mock_context_gl_)); - ASSERT_TRUE(testing::Mock::VerifyAndClear(&mock_gpu_channel_)); - delete gpu_command_buffer_proxy_; - mock_context_provider_.reset(); - gpu_channel_host_.reset(); - } - - void MockGpuChannel() { - // Simulate success, since we're not actually talking to the service - // in this test suite. - ON_CALL(mock_gpu_channel_, CreateCommandBuffer(_, _, _, _, _, _, _)) - .WillByDefault(Invoke( - [&](gpu::mojom::CreateCommandBufferParamsPtr params, - int32_t routing_id, base::UnsafeSharedMemoryRegion shared_state, - mojo::PendingAssociatedReceiver<gpu::mojom::CommandBuffer> - receiver, - mojo::PendingAssociatedRemote<gpu::mojom::CommandBufferClient> - client, - gpu::ContextResult* result, - gpu::Capabilities* capabilities) -> bool { - // There's no real GpuChannel pipe for this endpoint to use, so - // associate it with a dedicated pipe for these tests. This - // allows the CommandBufferProxyImpl to make calls on its - // CommandBuffer endpoint. - receiver.EnableUnassociatedUsage(); - *result = gpu::ContextResult::kSuccess; - return true; - })); - } - - void MockContextProvider() { - ON_CALL(*mock_context_provider_, BindToCurrentSequence()) - .WillByDefault(Return(gpu::ContextResult::kSuccess)); - ON_CALL(mock_context_gl_, GetGraphicsResetStatusKHR()) - .WillByDefault(Return(GL_NO_ERROR)); - ON_CALL(*mock_context_provider_, ContextGL()) - .WillByDefault(Return(&mock_context_gl_)); - - gpu_command_buffer_proxy_ = new gpu::CommandBufferProxyImpl( - gpu_channel_host_, &gpu_memory_buffer_manager_, - content::kGpuStreamIdDefault, - task_environment_.GetMainThreadTaskRunner()); - gpu_command_buffer_proxy_->Initialize( - gpu::kNullSurfaceHandle, nullptr, content::kGpuStreamPriorityDefault, - gpu::ContextCreationAttribs(), GURL()); - ON_CALL(*mock_context_provider_, GetCommandBufferProxy()) - .WillByDefault(Return(gpu_command_buffer_proxy_)); - } - - std::unique_ptr<CodecFactory> CreateCodecFactory( - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator) { - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - vea_provider; - fake_vea_provider_.Bind(vea_provider.InitWithNewPipeAndPassReceiver()); - -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) - mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory; - fake_media_codec_provider_.Bind( - interface_factory.InitWithNewPipeAndPassReceiver()); - return std::make_unique<CodecFactoryMojo>( - task_environment_.GetMainThreadTaskRunner(), - std::move(context_provider), enable_video_decode_accelerator, - enable_video_encode_accelerator, std::move(vea_provider), - std::move(interface_factory)); -#elif BUILDFLAG(IS_FUCHSIA) - mojo::PendingRemote<media::mojom::FuchsiaMediaCodecProvider> - media_codec_provider; - fake_media_codec_provider_.Bind( - media_codec_provider.InitWithNewPipeAndPassReceiver()); - return std::make_unique<CodecFactoryFuchsia>( - task_environment_.GetMainThreadTaskRunner(), - std::move(context_provider), enable_video_decode_accelerator, - enable_video_encode_accelerator, std::move(vea_provider), - std::move(media_codec_provider)); -#else - return std::make_unique<CodecFactoryDefault>( - task_environment_.GetMainThreadTaskRunner(), - std::move(context_provider), enable_video_decode_accelerator, - enable_video_encode_accelerator, std::move(vea_provider)); -#endif - } - - std::unique_ptr<GpuVideoAcceleratorFactoriesImpl> - CreateGpuVideoAcceleratorFactories(bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator) { - std::unique_ptr<CodecFactory> codec_factory = CreateCodecFactory( - mock_context_provider_, enable_video_decode_accelerator, - enable_video_encode_accelerator); - auto gpu_factories = GpuVideoAcceleratorFactoriesImpl::CreateForTesting( - gpu_channel_host_, task_environment_.GetMainThreadTaskRunner(), - task_environment_.GetMainThreadTaskRunner(), mock_context_provider_, - std::move(codec_factory), &gpu_memory_buffer_manager_, - true, /* enable_video_gpu_memory_buffers */ - true, /* enable_media_stream_gpu_memory_buffers */ - enable_video_decode_accelerator, enable_video_encode_accelerator); - - // Wait until all async IO messages (e.g. Mojo and FIDL) to be delieved - // and handled. - task_environment_.RunUntilIdle(); - - return gpu_factories; - } - - protected: - base::test::SingleThreadTaskEnvironment task_environment_{ - base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; - - NiceMock<gpu::MockGpuChannel> mock_gpu_channel_; - NiceMock<MockGLESInterface> mock_context_gl_; - viz::TestGpuMemoryBufferManager gpu_memory_buffer_manager_; - scoped_refptr<TestGpuChannelHost> gpu_channel_host_; - scoped_refptr<MockContextProviderCommandBuffer> mock_context_provider_; - gpu::CommandBufferProxyImpl* gpu_command_buffer_proxy_; - - FakeVEAProviderImpl fake_vea_provider_; - -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) - FakeInterfaceFactory fake_media_codec_provider_; -#elif BUILDFLAG(IS_FUCHSIA) - FakeFuchsiaMediaCodecProvide fake_media_codec_provider_; -#endif -}; - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, VideoDecoderAcceleratorDisabled) { - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, false); - - EXPECT_FALSE( - gpu_video_accelerator_factories->IsGpuVideoDecodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsDecoderSupportKnown()); - EXPECT_EQ(gpu_video_accelerator_factories->IsDecoderConfigSupported( - kH264BaseConfig), - media::GpuVideoAcceleratorFactories::Supported::kFalse); - EXPECT_EQ(gpu_video_accelerator_factories->GetDecoderType(), - media::VideoDecoderType::kUnknown); - - ASSERT_TRUE( - testing::Mock::VerifyAndClearExpectations(&mock_context_provider_)); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, VideoEncoderAcceleratorDisabled) { - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, false); - - EXPECT_FALSE( - gpu_video_accelerator_factories->IsGpuVideoEncodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsEncoderSupportKnown()); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, EncoderConfigsIsSupported) { - fake_vea_provider_.SetVideoEncodeAcceleratorSupportedProfiles( - {media::VideoEncodeAccelerator::SupportedProfile( - media::VideoCodecProfile::VP9PROFILE_MAX, kCodedSize)}); - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, true); - - EXPECT_TRUE( - gpu_video_accelerator_factories->IsGpuVideoEncodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsEncoderSupportKnown()); - base::test::TestFuture<void> future; - gpu_video_accelerator_factories->NotifyEncoderSupportKnown( - future.GetCallback()); - EXPECT_TRUE(future.Wait()); - auto supported_profiles = gpu_video_accelerator_factories - ->GetVideoEncodeAcceleratorSupportedProfiles(); - EXPECT_TRUE(supported_profiles.has_value()); - EXPECT_EQ(supported_profiles->size(), static_cast<size_t>(1)); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, EncoderConfigsIsNotSupported) { - fake_vea_provider_.SetVideoEncodeAcceleratorSupportedProfiles({}); - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, true); - - EXPECT_TRUE( - gpu_video_accelerator_factories->IsGpuVideoEncodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsEncoderSupportKnown()); - base::test::TestFuture<void> future; - gpu_video_accelerator_factories->NotifyEncoderSupportKnown( - future.GetCallback()); - EXPECT_TRUE(future.Wait()); - auto supported_profiles = gpu_video_accelerator_factories - ->GetVideoEncodeAcceleratorSupportedProfiles(); - EXPECT_TRUE(supported_profiles.has_value()); - EXPECT_TRUE(supported_profiles->empty()); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, CreateVideoEncodeAccelerator) { - fake_vea_provider_.SetVideoEncodeAcceleratorSupportedProfiles( - {media::VideoEncodeAccelerator::SupportedProfile( - media::VideoCodecProfile::VP9PROFILE_MAX, kCodedSize)}); - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, true); - - EXPECT_NE(gpu_video_accelerator_factories->CreateVideoEncodeAccelerator(), - nullptr); -} - -#ifdef GTEST_HAS_DEATH_TEST -using GpuVideoAcceleratorFactoriesImplDeathTest = - GpuVideoAcceleratorFactoriesImplTest; - -TEST_F(GpuVideoAcceleratorFactoriesImplDeathTest, - CreateVideoEncodeAcceleratorFailed) { - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, false); - - EXPECT_DCHECK_DEATH({ - EXPECT_EQ(gpu_video_accelerator_factories->CreateVideoEncodeAccelerator(), - nullptr); - }); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplDeathTest, CreateVideoDecoderFailed) { - testing::StrictMock<MockOverlayInfoCbHandler> cb_handler; - media::RequestOverlayInfoCB mock_cb = base::BindRepeating( - &MockOverlayInfoCbHandler::Call, base::Unretained(&cb_handler)); - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, false); - - EXPECT_DCHECK_DEATH({ - EXPECT_EQ(gpu_video_accelerator_factories->CreateVideoDecoder( - nullptr, std::move(mock_cb)), - nullptr); - }); -} -#endif // GTEST_HAS_DEATH_TEST - -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) || BUILDFLAG(IS_FUCHSIA) -TEST_F(GpuVideoAcceleratorFactoriesImplTest, DecoderConfigIsSupported) { - fake_media_codec_provider_.SetSupportedVideoDecoderConfigs( - {kH264MaxSupportedVideoDecoderConfig}); - - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(true, false); - - EXPECT_TRUE( - gpu_video_accelerator_factories->IsGpuVideoDecodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsDecoderSupportKnown()); - base::test::TestFuture<void> future; - gpu_video_accelerator_factories->NotifyDecoderSupportKnown( - future.GetCallback()); - EXPECT_TRUE(future.Wait()); - EXPECT_EQ(gpu_video_accelerator_factories->IsDecoderConfigSupported( - kH264BaseConfig), - media::GpuVideoAcceleratorFactories::Supported::kTrue); - EXPECT_NE(gpu_video_accelerator_factories->GetDecoderType(), - media::VideoDecoderType::kUnknown); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, DecoderConfigIsNotSupported) { - fake_media_codec_provider_.SetSupportedVideoDecoderConfigs( - {kH264MaxSupportedVideoDecoderConfig}); - - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(true, false); - - EXPECT_TRUE( - gpu_video_accelerator_factories->IsGpuVideoDecodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsDecoderSupportKnown()); - base::test::TestFuture<void> future; - gpu_video_accelerator_factories->NotifyDecoderSupportKnown( - future.GetCallback()); - EXPECT_TRUE(future.Wait()); - EXPECT_EQ( - gpu_video_accelerator_factories->IsDecoderConfigSupported(kVP9BaseConfig), - media::GpuVideoAcceleratorFactories::Supported::kFalse); -} - -TEST_F(GpuVideoAcceleratorFactoriesImplTest, CreateVideoDecoder) { - testing::StrictMock<MockOverlayInfoCbHandler> cb_handler; - media::RequestOverlayInfoCB mock_cb = base::BindRepeating( - &MockOverlayInfoCbHandler::Call, base::Unretained(&cb_handler)); - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(true, false); - - EXPECT_NE(gpu_video_accelerator_factories->CreateVideoDecoder( - nullptr, std::move(mock_cb)), - nullptr); -} -#else -TEST_F(GpuVideoAcceleratorFactoriesImplTest, DefaultCodecFactory) { - auto gpu_video_accelerator_factories = - CreateGpuVideoAcceleratorFactories(false, false); - - EXPECT_FALSE( - gpu_video_accelerator_factories->IsGpuVideoDecodeAcceleratorEnabled()); - EXPECT_TRUE(gpu_video_accelerator_factories->IsDecoderSupportKnown()); - base::test::TestFuture<void> future; - gpu_video_accelerator_factories->NotifyDecoderSupportKnown( - future.GetCallback()); - EXPECT_TRUE(future.Wait()); - EXPECT_EQ(gpu_video_accelerator_factories->IsDecoderConfigSupported( - kH264BaseConfig), - media::GpuVideoAcceleratorFactories::Supported::kFalse); -} -#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) || BUILDFLAG(IS_FUCHSIA) - -} // namespace content
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index b2d9c16d..9e09c53 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -4152,6 +4152,14 @@ } } +void RenderFrameImpl::OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) { + for (auto& observer : observers_) { + observer.OnMainFrameImageAdRectangleChanged(element_id, image_ad_rect); + } +} + void RenderFrameImpl::OnOverlayPopupAdDetected() { for (auto& observer : observers_) { observer.OnOverlayPopupAdDetected();
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index a42b940..3b55829 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -575,6 +575,9 @@ const gfx::Rect& main_frame_intersection_rect) override; void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) override; void WillSendRequest(blink::WebURLRequest& request, ForRedirect for_redirect) override; void OnOverlayPopupAdDetected() override;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 8820b82..1ab2dbae 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -75,7 +75,6 @@ #include "content/common/main_frame_counter.h" #include "content/common/process_visibility_tracker.h" #include "content/common/pseudonymization_salt.h" -#include "content/public/common/content_client.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_features.h" #include "content/public/common/content_paths.h" @@ -88,7 +87,6 @@ #include "content/renderer/agent_scheduling_group.h" #include "content/renderer/browser_exposed_renderer_interfaces.h" #include "content/renderer/effective_connection_type_helper.h" -#include "content/renderer/media/codec_factory.h" #include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h" #include "content/renderer/media/media_factory.h" #include "content/renderer/media/render_media_client.h" @@ -122,7 +120,6 @@ #include "media/video/gpu_video_accelerator_factories.h" #include "mojo/public/cpp/bindings/binder_map.h" #include "mojo/public/cpp/bindings/callback_helpers.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/message_pipe.h" #include "net/base/net_errors.h" @@ -204,16 +201,6 @@ #include <malloc.h> #endif -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) -#include "content/renderer/media/codec_factory_mojo.h" -#include "media/mojo/mojom/interface_factory.mojom.h" -#endif - -#if BUILDFLAG(IS_FUCHSIA) -#include "content/renderer/media/codec_factory_fuchsia.h" -#include "media/fuchsia/mojom/fuchsia_media.mojom.h" -#endif - #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX) #include "base/test/clang_profiling.h" #endif @@ -1060,6 +1047,7 @@ gpu::kGpuFeatureStatusEnabled); const bool enable_video_encode_accelerator = + #if BUILDFLAG(IS_LINUX) base::FeatureList::IsEnabled(media::kVaapiVideoEncodeLinux) && #else @@ -1088,17 +1076,31 @@ gpu_channel_host->gpu_info().overlay_info.supports_overlays); #endif // BUILDFLAG(IS_WIN) - auto codec_factory = CreateMediaCodecFactory(media_context_provider, - enable_video_decode_accelerator, - enable_video_encode_accelerator); + mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory; + BindHostReceiver(interface_factory.InitWithNewPipeAndPassReceiver()); + + mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> + vea_provider; + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled(media::kUseOutOfProcessVideoEncoding)) { + BindHostReceiver(vea_provider.InitWithNewPipeAndPassReceiver()); + } else { + gpu_->CreateVideoEncodeAcceleratorProvider( + vea_provider.InitWithNewPipeAndPassReceiver()); + } +#else + gpu_->CreateVideoEncodeAcceleratorProvider( + vea_provider.InitWithNewPipeAndPassReceiver()); +#endif + gpu_factories_.push_back(GpuVideoAcceleratorFactoriesImpl::Create( std::move(gpu_channel_host), base::SingleThreadTaskRunner::GetCurrentDefault(), GetMediaSequencedTaskRunner(), std::move(media_context_provider), - std::move(codec_factory), enable_video_gpu_memory_buffers, - enable_media_stream_gpu_memory_buffers, enable_video_decode_accelerator, - enable_video_encode_accelerator)); - + enable_video_gpu_memory_buffers, enable_media_stream_gpu_memory_buffers, + enable_video_decode_accelerator, enable_video_encode_accelerator, + std::move(interface_factory), std::move(vea_provider))); gpu_factories_.back()->SetRenderingColorSpace(rendering_color_space_); return gpu_factories_.back().get(); } @@ -1837,45 +1839,4 @@ attribution_os_support_ = attribution_os_support; } -std::unique_ptr<CodecFactory> RenderThreadImpl::CreateMediaCodecFactory( - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator) { - mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> - vea_provider; -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) - if (base::FeatureList::IsEnabled(media::kUseOutOfProcessVideoEncoding)) { - BindHostReceiver(vea_provider.InitWithNewPipeAndPassReceiver()); - } else { - gpu_->CreateVideoEncodeAcceleratorProvider( - vea_provider.InitWithNewPipeAndPassReceiver()); - } -#else - gpu_->CreateVideoEncodeAcceleratorProvider( - vea_provider.InitWithNewPipeAndPassReceiver()); -#endif - -#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) - mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory; - BindHostReceiver(interface_factory.InitWithNewPipeAndPassReceiver()); - return std::make_unique<CodecFactoryMojo>( - GetMediaSequencedTaskRunner(), context_provider, - enable_video_decode_accelerator, enable_video_encode_accelerator, - std::move(vea_provider), std::move(interface_factory)); -#elif BUILDFLAG(IS_FUCHSIA) - mojo::PendingRemote<media::mojom::FuchsiaMediaCodecProvider> - media_codec_provider; - BindHostReceiver(media_codec_provider.InitWithNewPipeAndPassReceiver()); - return std::make_unique<CodecFactoryFuchsia>( - GetMediaSequencedTaskRunner(), context_provider, - enable_video_decode_accelerator, enable_video_encode_accelerator, - std::move(vea_provider), std::move(media_codec_provider)); -#else - return std::make_unique<CodecFactoryDefault>( - GetMediaSequencedTaskRunner(), context_provider, - enable_video_decode_accelerator, enable_video_encode_accelerator, - std::move(vea_provider)); -#endif -} - } // namespace content
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index d4cbe57..d3dc1320 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -40,7 +40,6 @@ #include "content/common/shared_storage_worklet_service.mojom.h" #include "content/public/renderer/render_thread.h" #include "content/renderer/discardable_memory_utils.h" -#include "content/renderer/media/codec_factory.h" #include "gpu/ipc/client/gpu_channel_host.h" #include "ipc/ipc_sync_channel.h" #include "media/media_buildflags.h" @@ -468,11 +467,6 @@ void OnRendererInterfaceReceiver( mojo::PendingAssociatedReceiver<mojom::Renderer> receiver); - std::unique_ptr<CodecFactory> CreateMediaCodecFactory( - scoped_refptr<viz::ContextProviderCommandBuffer> context_provider, - bool enable_video_decode_accelerator, - bool enable_video_encode_accelerator); - scoped_refptr<discardable_memory::ClientDiscardableSharedMemoryManager> discardable_memory_allocator_;
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 94f0429..3b7d600 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -430,6 +430,7 @@ sources = [ "$root_gen_dir/base/tracing/protos/tracing_proto_resources.pak", + "$root_gen_dir/content/attribution_internals_resources.pak", "$root_gen_dir/content/browser/resources/media/media_internals_resources.pak", "$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak", "$root_gen_dir/content/content_resources.pak",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 928f2a63..02e3f16 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2585,7 +2585,6 @@ "../renderer/accessibility/ax_image_stopwords_unittest.cc", "../renderer/content_security_policy_util_unittest.cc", "../renderer/media/batching_media_log_unittest.cc", - "../renderer/media/gpu/gpu_video_accelerator_factories_impl_unittest.cc", "../renderer/media/inspector_media_event_handler_unittest.cc", "../renderer/media/renderer_webaudiodevice_impl_unittest.cc", "../renderer/render_thread_impl_unittest.cc", @@ -2755,7 +2754,6 @@ "//gin", "//gpu", "//gpu:test_support", - "//gpu/ipc/common:test_support", "//gpu/ipc/host", "//gpu/ipc/service", "//ipc:test_support", @@ -2787,7 +2785,6 @@ "//services/video_capture/public/cpp:mocks", "//services/video_capture/public/mojom", "//services/video_capture/public/mojom:constants", - "//services/viz/public/cpp/gpu", "//skia", "//sql", "//sql:test_support",
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt index 486280b..268a2e9b 100644 --- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt +++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-blink.txt
@@ -1,7 +1,7 @@ rootWebArea ++genericContainer ignored ++++genericContainer -++++++inputTime inputType='time' value='13:50:02.922' +++++++inputTime inputType='time' value='13:50:02.922' controlsIds=group ++++++++genericContainer ++++++++++genericContainer ++++++++++++spinButton name='Hours' placeholder='--' value='01' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=12.00 @@ -28,7 +28,7 @@ ++++++++++++++staticText name='PM' ++++++++++++++++inlineTextBox name='PM' ++++++++popUpButton name='Show time picker' -++++++++rootWebArea +++++++++group ++++++++++genericContainer ignored ++++++++++++genericContainer ignored ++++++++++++++genericContainer
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-fuchsia.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-fuchsia.txt index 98b4b473..82e1b365 100644 --- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-fuchsia.txt +++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-fuchsia.txt
@@ -28,7 +28,7 @@ ++++++++++++++STATIC_TEXT label='PM' ++++++++++++++++UNKNOWN label='PM' ++++++++UNKNOWN focusable label='Show time picker' actions='{DEFAULT}' -++++++++UNKNOWN focusable +++++++++UNKNOWN ++++++++++UNKNOWN hidden ++++++++++++UNKNOWN hidden ++++++++++++++UNKNOWN
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt index 5bb2b4c..623f670b 100644 --- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt +++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt
@@ -13,7 +13,7 @@ ++++++++++AXStaticText AXRoleDescription='text' AXValue=' ' ++++++++++AXIncrementor AXDescription='AM/PM' AXRoleDescription='stepper' AXValue=2 ++++++AXPopUpButton AXDescription='Show time picker' AXRoleDescription='pop up button' -++++++AXWebArea AXRoleDescription='HTML content' +++++++AXGroup AXSubrole=AXApplicationGroup AXRoleDescription='group' ++++++++AXGroup AXRoleDescription='group' ++++++++++AXGroup AXRoleDescription='group' ++++++++++++AXList AXDescription='Hours' AXRoleDescription='list box'
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-uia-win.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-uia-win.txt index 1f399105..c63684a 100644 --- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-uia-win.txt
@@ -1,6 +1,6 @@ Document ++Group IsControlElement=false -++++Group LocalizedControlType='time picker' Value.Value='13:50:02.922' +++++Group LocalizedControlType='time picker' ControllerFor='{group}' Value.Value='13:50:02.922' ++++++Group IsControlElement=false ++++++++Group IsControlElement=false ++++++++++Spinner Name='Hours' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=12.00 RangeValue.Minimum=1.00 RangeValue.Value=1.00 Value.Value='01' @@ -14,7 +14,7 @@ ++++++++++Spinner Name='AM/PM' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=2.00 RangeValue.Minimum=1.00 RangeValue.Value=2.00 Value.Value='PM' ++++++Button Name='Show time picker' ExpandCollapse.ExpandCollapseState='Collapsed' ++++++Pane Name='Chrome Legacy Window' IsControlElement=false -++++++++Document +++++++++Group IsControlElement=false ++++++++++Group IsControlElement=false ++++++++++++Group ++++++++++++++List Name='Hours' Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-win.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-win.txt index 51e4e77..a10d029 100644 --- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-win.txt +++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-win.txt
@@ -13,7 +13,7 @@ ++++++++++ROLE_SYSTEM_STATICTEXT name=' ' ia2_hypertext=' ' ++++++++++ROLE_SYSTEM_SPINBUTTON name='AM/PM' value='PM' FOCUSABLE ++++++ROLE_SYSTEM_BUTTONMENU name='Show time picker' FOCUSABLE HASPOPUP -++++++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>' +++++++ROLE_SYSTEM_GROUPING ia2_hypertext='<obj0>' ++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>' ++++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0><obj1><obj2><obj3><obj4>' ++++++++++++ROLE_SYSTEM_LIST name='Hours' FOCUSABLE ia2_hypertext='<obj0><obj1><obj2><obj3><obj4><obj5><obj6><obj7><obj8><obj9><obj10><obj11>'
diff --git a/docs/autofill/chrome_payments_flows.md b/docs/autofill/chrome_payments_flows.md index c5c4c04..99cc163 100644 --- a/docs/autofill/chrome_payments_flows.md +++ b/docs/autofill/chrome_payments_flows.md
@@ -83,17 +83,17 @@ 1. The user submits a form, triggering [AutofillManager::OnFormSubmitted](https://cs.chromium.org/chromium/src/components/autofill/core/browser/autofill_manager.cc?l=368&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d). - If the form was autofillable, FormDataImporter::ImportFormData [is + If the form was autofillable, FormDataImporter::ExtractFormData [is called](https://cs.chromium.org/chromium/src/components/autofill/core/browser/autofill_manager.cc?l=392-393&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) -2. An inner [FormDataImporter::ImportFormData +2. An inner [FormDataImporter::ExtractFormData helper](https://cs.chromium.org/chromium/src/components/autofill/core/browser/form_data_importer.cc?l=169&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) - is called, which begins the process of importing both credit card and + is called, which begins the process of extracting both credit card and address profile information -3. [FormDataImporter::ImportCreditCard](https://cs.chromium.org/chromium/src/components/autofill/core/browser/form_data_importer.cc?l=307&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) +3. [FormDataImporter::ExtractCreditCard](https://cs.chromium.org/chromium/src/components/autofill/core/browser/form_data_importer.cc?l=307&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) is called which tries to detect if a new credit card was entered on the - form, storing it in `|imported_credit_card|` if so -4. [FormDataImporter::ImportAddressProfiles](https://cs.chromium.org/chromium/src/components/autofill/core/browser/form_data_importer.cc?l=196&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) - is called, which tries to [import one address profile per form + form, storing it in `imported_credit_card` if so +4. [FormDataImporter::ExtractAddressProfiles](https://cs.chromium.org/chromium/src/components/autofill/core/browser/form_data_importer.cc?l=196&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) + is called, which tries to [extract one address profile per form section](https://cs.chromium.org/chromium/src/components/autofill/core/browser/form_data_importer.cc?l=222&rcl=ab8d0ea46daf7673a53524a3708f0ffd1ea9ee2d) (maximum of 2) 5. If the submitted form [included a credit @@ -198,4 +198,3 @@ [CreditCardSaveManager::OnDidUploadCard](https://cs.chromium.org/chromium/src/components/autofill/core/browser/credit_card_save_manager.cc?l=215&rcl=6ad45bcd758ad6eaba1da3a71b909f7ca7b46217), which, on a success, saves the credit card as a FULL_SERVER_CARD (so it doesn’t need to be unmasked on next use on the same device) -
diff --git a/docs/infra/trybot_usage.md b/docs/infra/trybot_usage.md index da8aa39..bf8871e 100644 --- a/docs/infra/trybot_usage.md +++ b/docs/infra/trybot_usage.md
@@ -9,8 +9,8 @@ - Trybots include all platforms for which we currently build Chromium, though they may not support all configurations built on CI. -- The commit queue runs a subset of available trybots. See [here][1] for more - information. +- The commit queue (CQ) runs a subset of available trybots. See [here][1] for + more information. - trybots can be manually invoked via `git cl try` or the "Choose Trybots" UI in gerrit. - Any committer can use the trybots.
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.h b/extensions/browser/api/declarative_net_request/ruleset_manager.h index ae949f3..5cde9ad1 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.h +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.h
@@ -100,6 +100,8 @@ void OnRenderFrameDeleted(content::RenderFrameHost* host); void OnDidFinishNavigation(content::NavigationHandle* navigation_handle); + bool has_rulesets() const { return !rulesets_.empty(); } + // Returns the number of CompositeMatchers currently being managed. size_t GetMatcherCountForTest() const { return rulesets_.size(); }
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc b/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc index 69d7c5a9..fd60b0e 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc +++ b/extensions/browser/api/networking_private/networking_private_chromeos_unittest.cc
@@ -215,15 +215,14 @@ base::Value("test_min")); SetDeviceProperty(kCellularDevicePath, shill::kModelIdProperty, base::Value("test_model_id")); - std::unique_ptr<base::Value> apn = - DictionaryBuilder() - .Set(shill::kApnProperty, "test-apn") - .Set(shill::kApnUsernameProperty, "test-user") - .Set(shill::kApnPasswordProperty, "test-password") - .Set(shill::kApnAuthenticationProperty, "chap") - .Build(); + base::Value apn(DictionaryBuilder() + .Set(shill::kApnProperty, "test-apn") + .Set(shill::kApnUsernameProperty, "test-user") + .Set(shill::kApnPasswordProperty, "test-password") + .Set(shill::kApnAuthenticationProperty, "chap") + .Build()); base::Value apn_list(base::Value::Type::LIST); - apn_list.Append(apn->Clone()); + apn_list.GetList().Append(apn.Clone()); SetDeviceProperty(kCellularDevicePath, shill::kCellularApnListProperty, apn_list); @@ -246,9 +245,9 @@ shill::kRoamingStateProperty, base::Value(shill::kRoamingStateHome)); service_test()->SetServiceProperty(kCellularServicePath, - shill::kCellularApnProperty, *apn); + shill::kCellularApnProperty, apn); service_test()->SetServiceProperty( - kCellularServicePath, shill::kCellularLastGoodApnProperty, *apn); + kCellularServicePath, shill::kCellularLastGoodApnProperty, apn); profile_test()->AddService(kUserProfilePath, kCellularServicePath); @@ -1076,7 +1075,7 @@ ASSERT_TRUE(result); - std::unique_ptr<base::Value> expected_result = + base::Value::Dict expected_result = DictionaryBuilder() .Set("Cellular", DictionaryBuilder() @@ -1103,7 +1102,7 @@ .Set("Type", "Cellular") .Build(); - EXPECT_EQ(*expected_result, *result); + EXPECT_EQ(base::Value(std::move(expected_result)), *result); } TEST_F(NetworkingPrivateApiTest, GetCellularPropertiesFromWebUi) { @@ -1119,14 +1118,13 @@ ASSERT_TRUE(result); - std::unique_ptr<base::Value> expected_apn = - DictionaryBuilder() - .Set("AccessPointName", "test-apn") - .Set("Username", "test-user") - .Set("Password", "test-password") - .Set("Authentication", "chap") - .Build(); - std::unique_ptr<base::Value> expected_result = + base::Value::Dict expected_apn = DictionaryBuilder() + .Set("AccessPointName", "test-apn") + .Set("Username", "test-user") + .Set("Password", "test-password") + .Set("Authentication", "chap") + .Build(); + base::Value::Dict expected_result = DictionaryBuilder() .Set("Cellular", DictionaryBuilder() @@ -1149,14 +1147,10 @@ .Set("NetworkTechnology", "GSM") .Set("RoamingState", "Home") .Set("Scanning", false) - .Set("APNList", ListBuilder() - .Append(base::Value::ToUniquePtrValue( - expected_apn->Clone())) - .Build()) - .Set("APN", - base::Value::ToUniquePtrValue(expected_apn->Clone())) - .Set("LastGoodAPN", - base::Value::ToUniquePtrValue(expected_apn->Clone())) + .Set("APNList", + ListBuilder().Append(expected_apn.Clone()).Build()) + .Set("APN", expected_apn.Clone()) + .Set("LastGoodAPN", expected_apn.Clone()) .Build()) .Set("ConnectionState", "Connected") .Set("GUID", "cellular_guid") @@ -1168,7 +1162,7 @@ .Set("Type", "Cellular") .Build(); - EXPECT_EQ(*expected_result, *result); + EXPECT_EQ(base::Value(std::move(expected_result)), *result); } TEST_F(NetworkingPrivateApiTest, ForgetSharedNetwork) {
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 3fbe300d..c800df6 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -1166,6 +1166,9 @@ CreateEventDetails(*request, extra_info_spec)); event_details->SetRequestBody(request); + request_time_tracker_->LogBeforeRequestDispatchTime(request->id, + base::TimeTicks::Now()); + initialize_blocked_requests |= DispatchEvent( browser_context, request, listeners, std::move(event_details)); } @@ -1181,50 +1184,76 @@ // currently only depend on the request url, initiator and resource type, // which should stay the same during the diffierent network request stages. A // redirect should cause another OnBeforeRequest call. - const std::vector<DNRRequestAction>& actions = + declarative_net_request::RulesetManager* ruleset_manager = declarative_net_request::RulesMonitorService::Get(browser_context) - ->ruleset_manager() - ->EvaluateRequest(*request, is_incognito_context); - for (const auto& action : actions) { - switch (action.type) { - case DNRRequestAction::Type::BLOCK: - ClearPendingCallbacks(*request); - DCHECK_EQ(1u, actions.size()); - OnDNRActionMatched(browser_context, *request, action); - RecordNetworkRequestBlocked(request->ukm_source_id, - action.extension_id); - return net::ERR_BLOCKED_BY_CLIENT; - case DNRRequestAction::Type::COLLAPSE: - ClearPendingCallbacks(*request); - DCHECK_EQ(1u, actions.size()); - OnDNRActionMatched(browser_context, *request, action); - *should_collapse_initiator = true; - RecordNetworkRequestBlocked(request->ukm_source_id, - action.extension_id); - return net::ERR_BLOCKED_BY_CLIENT; - case DNRRequestAction::Type::ALLOW: - case DNRRequestAction::Type::ALLOW_ALL_REQUESTS: - DCHECK_EQ(1u, actions.size()); - OnDNRActionMatched(browser_context, *request, action); - break; - case DNRRequestAction::Type::REDIRECT: - case DNRRequestAction::Type::UPGRADE: - ClearPendingCallbacks(*request); - DCHECK_EQ(1u, actions.size()); - DCHECK(action.redirect_url); - OnDNRActionMatched(browser_context, *request, action); - *new_url = action.redirect_url.value(); - return net::OK; - case DNRRequestAction::Type::MODIFY_HEADERS: - // Unlike other actions, allow web request extensions to intercept the - // request here. The headers will be modified during subsequent request - // stages. - DCHECK( - base::ranges::all_of(*request->dnr_actions, [](const auto& action) { - return action.type == DNRRequestAction::Type::MODIFY_HEADERS; - })); - break; + ->ruleset_manager(); + + if (ruleset_manager->has_rulesets()) { + request_time_tracker_->LogBeforeRequestDNRStartTime(request->id, + base::TimeTicks::Now()); + + auto record_completion_time = [](ExtensionWebRequestTimeTracker* tracker, + int64_t request_id) { + tracker->LogBeforeRequestDNRCompletionTime(request_id, + base::TimeTicks::Now()); + }; + + const std::vector<DNRRequestAction>& actions = + ruleset_manager->EvaluateRequest(*request, is_incognito_context); + base::ScopedClosureRunner scoped_timer; + if (!actions.empty()) { + // We only record completion time if there's at least one relevant rule. + // Otherwise, we'd record evaluation for every request even if the user + // only had a single rule added. + scoped_timer = base::ScopedClosureRunner(base::BindOnce( + record_completion_time, request_time_tracker_.get(), request->id)); } + + for (const auto& action : actions) { + switch (action.type) { + case DNRRequestAction::Type::BLOCK: + ClearPendingCallbacks(*request); + DCHECK_EQ(1u, actions.size()); + OnDNRActionMatched(browser_context, *request, action); + RecordNetworkRequestBlocked(request->ukm_source_id, + action.extension_id); + return net::ERR_BLOCKED_BY_CLIENT; + case DNRRequestAction::Type::COLLAPSE: + ClearPendingCallbacks(*request); + DCHECK_EQ(1u, actions.size()); + OnDNRActionMatched(browser_context, *request, action); + *should_collapse_initiator = true; + RecordNetworkRequestBlocked(request->ukm_source_id, + action.extension_id); + return net::ERR_BLOCKED_BY_CLIENT; + case DNRRequestAction::Type::ALLOW: + case DNRRequestAction::Type::ALLOW_ALL_REQUESTS: + DCHECK_EQ(1u, actions.size()); + OnDNRActionMatched(browser_context, *request, action); + break; + case DNRRequestAction::Type::REDIRECT: + case DNRRequestAction::Type::UPGRADE: + ClearPendingCallbacks(*request); + DCHECK_EQ(1u, actions.size()); + DCHECK(action.redirect_url); + OnDNRActionMatched(browser_context, *request, action); + *new_url = action.redirect_url.value(); + return net::OK; + case DNRRequestAction::Type::MODIFY_HEADERS: + // Unlike other actions, allow web request extensions to intercept + // the request here. The headers will be modified during subsequent + // request stages. + DCHECK(base::ranges::all_of( + *request->dnr_actions, [](const auto& action) { + return action.type == DNRRequestAction::Type::MODIFY_HEADERS; + })); + break; + } + } + } else { + // Later methods require `dnr_actions` to be populated; give it an empty + // set. + request->dnr_actions = std::vector<DNRRequestAction>(); } if (!initialize_blocked_requests) @@ -2489,6 +2518,8 @@ // Ensure that the response is for the event we are blocked on. DCHECK_EQ(blocked_request.event, GetEventTypeFromEventName(event_name)); + // Cache the event type; we use it below. + EventTypes request_event = blocked_request.event; int num_handlers_blocking = --blocked_request.num_handlers_blocking; CHECK_GE(num_handlers_blocking, 0); @@ -2505,8 +2536,16 @@ blocked_request.response_deltas.push_back(std::move(delta)); } - if (num_handlers_blocking == 0) + if (num_handlers_blocking == 0) { ExecuteDeltas(browser_context, blocked_request.request, true); + // Note: `blocked_request` can be deleted here, depending on the outcome + // of ExecuteDeltas(). Use the cached `request_event` and `request_id` + // instead of using `blocked_request`. + if (request_event == kOnBeforeRequest) { + request_time_tracker_->LogBeforeRequestCompletionTime( + request_id, base::TimeTicks::Now()); + } + } } void ExtensionWebRequestEventRouter::SendMessages(
diff --git a/extensions/browser/api/web_request/web_request_time_tracker.cc b/extensions/browser/api/web_request/web_request_time_tracker.cc index 2627b19..a39c6fc 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker.cc +++ b/extensions/browser/api/web_request/web_request_time_tracker.cc
@@ -28,6 +28,43 @@ log.has_extra_headers_listener = has_extra_headers_listener; } +void ExtensionWebRequestTimeTracker::LogBeforeRequestDispatchTime( + int64_t request_id, + base::TimeTicks dispatch_time) { + auto iter = request_time_logs_.find(request_id); + DCHECK(iter != request_time_logs_.end()); + iter->second.before_request_listener_dispatch_time = dispatch_time; +} + +void ExtensionWebRequestTimeTracker::LogBeforeRequestCompletionTime( + int64_t request_id, + base::TimeTicks completion_time) { + auto iter = request_time_logs_.find(request_id); + if (iter == request_time_logs_.end()) { + // This probably *shouldn't* happen, but there's enough subtlety in handling + // network requests that we handle it gracefully. + return; + } + + iter->second.before_request_listener_completion_time = completion_time; +} + +void ExtensionWebRequestTimeTracker::LogBeforeRequestDNRStartTime( + int64_t request_id, + base::TimeTicks start_time) { + auto iter = request_time_logs_.find(request_id); + DCHECK(iter != request_time_logs_.end()); + iter->second.before_request_dnr_start_time = start_time; +} + +void ExtensionWebRequestTimeTracker::LogBeforeRequestDNRCompletionTime( + int64_t request_id, + base::TimeTicks completion_time) { + auto iter = request_time_logs_.find(request_id); + DCHECK(iter != request_time_logs_.end()); + iter->second.before_request_dnr_completion_time = completion_time; +} + void ExtensionWebRequestTimeTracker::LogRequestEndTime( int64_t request_id, const base::TimeTicks& end_time) { @@ -70,6 +107,47 @@ base::ClampRound(log.block_duration / request_duration * 100); UMA_HISTOGRAM_PERCENTAGE("Extensions.NetworkDelayPercentage", percentage); } + + // Record the time spent in listeners in onBeforeRequest. Only do this if + // we have a time for both the dispatch and completion time (we may not, + // if the request were canceled). + if (!log.before_request_listener_dispatch_time.is_null() && + !log.before_request_listener_completion_time.is_null()) { + base::TimeDelta listener_time = + log.before_request_listener_completion_time - + log.before_request_listener_dispatch_time; + // Because the DNR actions are calculated right after the event is + // dispatched, we separate these into different metrics (so that we can + // differentiate between times that include declarativeNetRequest rule + // matching and those that don't). + if (log.before_request_dnr_start_time.is_null()) { + UMA_HISTOGRAM_TIMES( + "Extensions.WebRequest.BeforeRequestListenerEvaluationTime." + "WebRequestOnly", + listener_time); + } else { // Both webRequest and DNR handlers. + UMA_HISTOGRAM_TIMES( + "Extensions.WebRequest.BeforeRequestListenerEvaluationTime." + "WebRequestAndDeclarativeNetRequest", + listener_time); + } + } + + if (!log.before_request_dnr_completion_time.is_null()) { + // Since declarativeNetRequest handlers are evaluated synchronously in the + // same method, if there's a completion time, there should always be a + // start time. (The inverse is not true, since we only log completion time + // if there was at least one relevant action.) + DCHECK(!log.before_request_dnr_start_time.is_null()); + // DeclarativeNetRequest handlers also aren't really affected by webRequest + // listeners, so no need to split up the time depending on whether there + // were webRequest listeners. + UMA_HISTOGRAM_TIMES( + "Extensions.WebRequest." + "BeforeRequestDeclarativeNetRequestEvaluationTime", + log.before_request_dnr_completion_time - + log.before_request_dnr_start_time); + } } void ExtensionWebRequestTimeTracker::IncrementTotalBlockTime(
diff --git a/extensions/browser/api/web_request/web_request_time_tracker.h b/extensions/browser/api/web_request/web_request_time_tracker.h index b8c544e..e3728b90 100644 --- a/extensions/browser/api/web_request/web_request_time_tracker.h +++ b/extensions/browser/api/web_request/web_request_time_tracker.h
@@ -35,6 +35,27 @@ bool has_listener, bool has_extra_headers_listener); + // Records the time at which an onBeforeRequest event was dispatched to + // listeners. + void LogBeforeRequestDispatchTime(int64_t request_id, + base::TimeTicks dispatch_time); + + // Records the time at which an onBeforeRequest event received a response + // from all blocking listeners and the responses have been handled. Only + // called if there was at least one blocking listener. + void LogBeforeRequestCompletionTime(int64_t request_id, + base::TimeTicks completion_time); + + // Records the time at which Chrome started to evaluate declarativeNetRequest + // rules at the beginning of a request. + void LogBeforeRequestDNRStartTime(int64_t request_id, + base::TimeTicks start_time); + + // Records the time at which Chrome has completed handling + // declarativeNetRequest rules. Only called if at least one rule was applied. + void LogBeforeRequestDNRCompletionTime(int64_t request_id, + base::TimeTicks completion_time); + // Records the time that a request either completed or encountered an error. void LogRequestEndTime(int64_t request_id, const base::TimeTicks& end_time); @@ -55,7 +76,13 @@ // Timing information for a single request. struct RequestTimeLog { base::TimeTicks request_start_time; + base::TimeTicks before_request_listener_dispatch_time; + base::TimeTicks before_request_dnr_start_time; + base::TimeTicks before_request_dnr_completion_time; + base::TimeTicks before_request_listener_completion_time; + base::TimeDelta block_duration; + bool has_listener = false; bool has_extra_headers_listener = false;
diff --git a/extensions/browser/content_verifier/test_utils.cc b/extensions/browser/content_verifier/test_utils.cc index a026351..5ec68db 100644 --- a/extensions/browser/content_verifier/test_utils.cc +++ b/extensions/browser/content_verifier/test_utils.cc
@@ -488,18 +488,22 @@ .Build()); } - return DictionaryBuilder() - .Set("item_id", extension_id_) - .Set("item_version", "1.0") - .Set("content_hashes", ListBuilder() - .Append(DictionaryBuilder() - .Set("format", "treehash") - .Set("block_size", block_size) - .Set("hash_block_size", block_size) - .Set("files", files.Build()) - .Build()) - .Build()) - .Build(); + base::Value::Dict result = + DictionaryBuilder() + .Set("item_id", extension_id_) + .Set("item_version", "1.0") + .Set("content_hashes", + ListBuilder() + .Append(DictionaryBuilder() + .Set("format", "treehash") + .Set("block_size", block_size) + .Set("hash_block_size", block_size) + .Set("files", files.Build()) + .Build()) + .Build()) + .Build(); + + return std::make_unique<base::Value>(std::move(result)); } // Other stuff ----------------------------------------------------------------
diff --git a/extensions/common/extension_builder_unittest.cc b/extensions/common/extension_builder_unittest.cc index 62d7094..2168bcb 100644 --- a/extensions/common/extension_builder_unittest.cc +++ b/extensions/common/extension_builder_unittest.cc
@@ -137,7 +137,7 @@ TEST(ExtensionBuilderTest, MergeManifest) { DictionaryBuilder connectable; connectable.Set("matches", ListBuilder().Append("*://example.com/*").Build()); - std::unique_ptr<base::DictionaryValue> connectable_value = + base::Value::Dict connectable_value = DictionaryBuilder() .Set("externally_connectable", connectable.Build()) .Build();
diff --git a/extensions/common/permissions/usb_device_permission_unittest.cc b/extensions/common/permissions/usb_device_permission_unittest.cc index b35f9d4..56eddf2 100644 --- a/extensions/common/permissions/usb_device_permission_unittest.cc +++ b/extensions/common/permissions/usb_device_permission_unittest.cc
@@ -63,7 +63,7 @@ } scoped_refptr<const Extension> CreateTestApp( - std::unique_ptr<base::Value> usb_device_permission) { + base::Value usb_device_permission) { return ExtensionBuilder() .SetManifest( DictionaryBuilder() @@ -107,14 +107,13 @@ } TEST(USBDevicePermissionTest, CheckVendorAndProductId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x138c) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x138c) + .Build()); UsbDevicePermissionData permission_data; - ASSERT_TRUE(permission_data.FromValue(permission_data_value.get())); + ASSERT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -147,14 +146,13 @@ } TEST(USBDevicePermissionTest, CheckInterfaceId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x138c) - .Set("interfaceId", 3) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x138c) + .Set("interfaceId", 3) + .Build()); UsbDevicePermissionData permission_data; - ASSERT_TRUE(permission_data.FromValue(permission_data_value.get())); + ASSERT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -185,10 +183,10 @@ } TEST(USBDevicePermissionTest, InterfaceClass) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder().Set("interfaceClass", 3).Build(); + base::Value permission_data_value( + DictionaryBuilder().Set("interfaceClass", 3).Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -224,13 +222,12 @@ } TEST(USBDevicePermissionTest, InterfaceClassWithVendorId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("interfaceClass", 3) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("interfaceClass", 3) + .Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -274,13 +271,12 @@ } TEST(USBDevicePermissionTest, CheckHidUsbAgainstInterfaceClass) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("interfaceClass", 3) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("interfaceClass", 3) + .Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -321,13 +317,12 @@ } TEST(USBDevicePermissionTest, CheckHidUsbAgainstDeviceIds) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x138c) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x138c) + .Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -350,13 +345,12 @@ } TEST(USBDevicePermissionTest, CheckDeviceAgainstDeviceIds) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x138c) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x138c) + .Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -383,10 +377,10 @@ } TEST(USBDevicePermissionTest, CheckDeviceAgainstDeviceClass) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder().Set("interfaceClass", 0x9).Build(); + base::Value permission_data_value( + DictionaryBuilder().Set("interfaceClass", 0x9).Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -432,10 +426,10 @@ } TEST(USBDevicePermissionTest, IgnoreNullDeviceClass) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder().Set("interfaceClass", 0).Build(); + base::Value permission_data_value( + DictionaryBuilder().Set("interfaceClass", 0).Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -457,10 +451,10 @@ } TEST(USBDevicePermissionTest, CheckDeviceAgainstInterfaceClass) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder().Set("interfaceClass", 0x3).Build(); + base::Value permission_data_value( + DictionaryBuilder().Set("interfaceClass", 0x3).Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -543,14 +537,13 @@ } TEST(USBDevicePermissionTest, CheckDeviceAndInterfaceId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x138c) - .Set("interfaceId", 3) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x138c) + .Set("interfaceId", 3) + .Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -578,13 +571,12 @@ TEST(USBDevicePermissionTest, CheckDeviceAndInterfaceIDAgainstMissingInterfaceId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x138c) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x138c) + .Build()); UsbDevicePermissionData permission_data; - EXPECT_TRUE(permission_data.FromValue(permission_data_value.get())); + EXPECT_TRUE(permission_data.FromValue(&permission_data_value)); scoped_refptr<const Extension> app = CreateTestApp(std::move(permission_data_value)); @@ -601,39 +593,39 @@ } TEST(USBDevicePermissionTest, InvalidPermission_NoVendorId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("productId", 0x138c) - .Set("interfaceClass", 3) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("productId", 0x138c) + .Set("interfaceClass", 3) + .Build()); UsbDevicePermissionData permission_data; - ASSERT_FALSE(permission_data.FromValue(permission_data_value.get())); + ASSERT_FALSE(permission_data.FromValue(&permission_data_value)); } TEST(USBDevicePermissionTest, InvalidPermission_OnlyVendorId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder().Set("vendorId", 0x02ad).Build(); + base::Value permission_data_value( + DictionaryBuilder().Set("vendorId", 0x02ad).Build()); UsbDevicePermissionData permission_data; - ASSERT_FALSE(permission_data.FromValue(permission_data_value.get())); + ASSERT_FALSE(permission_data.FromValue(&permission_data_value)); } TEST(USBDevicePermissionTest, InvalidPermission_NoProductIdWithInterfaceId) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder().Set("vendorId", 0x02ad).Set("interfaceId", 3).Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("interfaceId", 3) + .Build()); UsbDevicePermissionData permission_data; - ASSERT_FALSE(permission_data.FromValue(permission_data_value.get())); + ASSERT_FALSE(permission_data.FromValue(&permission_data_value)); } TEST(USBDevicePermissionTest, RejectInterfaceIdIfInterfaceClassPresent) { - std::unique_ptr<base::Value> permission_data_value = - DictionaryBuilder() - .Set("vendorId", 0x02ad) - .Set("productId", 0x128c) - .Set("interfaceId", 3) - .Set("interfaceClass", 7) - .Build(); + base::Value permission_data_value(DictionaryBuilder() + .Set("vendorId", 0x02ad) + .Set("productId", 0x128c) + .Set("interfaceId", 3) + .Set("interfaceClass", 7) + .Build()); UsbDevicePermissionData permission_data; - ASSERT_FALSE(permission_data.FromValue(permission_data_value.get())); + ASSERT_FALSE(permission_data.FromValue(&permission_data_value)); } } // namespace extensions
diff --git a/extensions/common/value_builder.cc b/extensions/common/value_builder.cc index bb41c44b..5bf412e 100644 --- a/extensions/common/value_builder.cc +++ b/extensions/common/value_builder.cc
@@ -13,22 +13,17 @@ // DictionaryBuilder -DictionaryBuilder::DictionaryBuilder() : dict_(new base::DictionaryValue) {} - -DictionaryBuilder::DictionaryBuilder(const base::DictionaryValue& init) - : dict_(base::DictionaryValue::From( - base::Value::ToUniquePtrValue(init.Clone()))) {} +DictionaryBuilder::DictionaryBuilder() = default; DictionaryBuilder::DictionaryBuilder(const base::Value::Dict& init) - : dict_(base::DictionaryValue::From( - base::Value::ToUniquePtrValue(base::Value(init.Clone())))) {} + : dict_(init.Clone()) {} DictionaryBuilder::~DictionaryBuilder() = default; std::string DictionaryBuilder::ToJSON() const { std::string json; base::JSONWriter::WriteWithOptions( - *dict_, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); + dict_, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); return json; }
diff --git a/extensions/common/value_builder.h b/extensions/common/value_builder.h index 84ed0d53..30fd7d2 100644 --- a/extensions/common/value_builder.h +++ b/extensions/common/value_builder.h
@@ -45,7 +45,6 @@ class DictionaryBuilder { public: DictionaryBuilder(); - explicit DictionaryBuilder(const base::DictionaryValue& init); explicit DictionaryBuilder(const base::Value::Dict& init); DictionaryBuilder(const DictionaryBuilder&) = delete; @@ -53,23 +52,22 @@ ~DictionaryBuilder(); - // Can only be called once, after which it's invalid to use the builder. - base::Value::Dict BuildDict() { - base::Value::Dict result = std::move(*dict_).TakeDict(); - dict_.reset(); + // Deprecated: Use Build instead. + base::Value::Dict BuildDict() { return Build(); } + + base::Value::Dict Build() { + base::Value::Dict result = std::move(dict_); + dict_ = base::Value::Dict(); return result; } - // DEPRECATED version of BuildDict(). - std::unique_ptr<base::DictionaryValue> Build() { return std::move(dict_); } - // Immediately serializes the current state to JSON. Can be called as many // times as you like. std::string ToJSON() const; template <typename T> DictionaryBuilder& Set(base::StringPiece key, T in_value) { - dict_->GetDict().Set(key, std::move(in_value)); + dict_.Set(key, std::move(in_value)); return *this; } @@ -80,12 +78,12 @@ // a base::Value (or one of its subclasses). template <typename T> DictionaryBuilder& Set(base::StringPiece key, std::unique_ptr<T> in_value) { - dict_->SetKey(key, std::move(*in_value)); + dict_.Set(key, std::move(*in_value)); return *this; } private: - std::unique_ptr<base::DictionaryValue> dict_; + base::Value::Dict dict_; }; class ListBuilder {
diff --git a/extensions/renderer/api/messaging/native_renderer_messaging_service_unittest.cc b/extensions/renderer/api/messaging/native_renderer_messaging_service_unittest.cc index 196171b..acaba87 100644 --- a/extensions/renderer/api/messaging/native_renderer_messaging_service_unittest.cc +++ b/extensions/renderer/api/messaging/native_renderer_messaging_service_unittest.cc
@@ -151,8 +151,7 @@ tab_connection_info.frame_id = 0; const int tab_id = 10; GURL source_url("http://example.com"); - tab_connection_info.tab = - DictionaryBuilder().Set("tabId", tab_id).BuildDict(); + tab_connection_info.tab = DictionaryBuilder().Set("tabId", tab_id).Build(); ExtensionMsg_ExternalConnectionInfo external_connection_info; external_connection_info.target_id = extension()->id(); external_connection_info.source_endpoint = @@ -191,8 +190,8 @@ .Set("tab", DictionaryBuilder().Set("tabId", tab_id).BuildDict()) .Set("url", source_url.spec()) .Set("id", extension()->id()) - .BuildDict(); - EXPECT_EQ(ValueToString(expected_sender), + .Build(); + EXPECT_EQ(ValueToString(base::Value(std::move(expected_sender))), GetStringPropertyFromObject(context->Global(), context, "sender")); } @@ -497,8 +496,7 @@ tab_connection_info.frame_id = 0; const int tab_id = 10; GURL source_url("http://example.com"); - tab_connection_info.tab = - DictionaryBuilder().Set("tabId", tab_id).BuildDict(); + tab_connection_info.tab = DictionaryBuilder().Set("tabId", tab_id).Build(); ExtensionMsg_ExternalConnectionInfo external_connection_info; external_connection_info.target_id = extension()->id(); external_connection_info.source_endpoint = @@ -570,8 +568,7 @@ tab_connection_info.frame_id = 0; const int tab_id = 10; GURL source_url("http://example.com"); - tab_connection_info.tab = - DictionaryBuilder().Set("tabId", tab_id).BuildDict(); + tab_connection_info.tab = DictionaryBuilder().Set("tabId", tab_id).Build(); ExtensionMsg_ExternalConnectionInfo external_connection_info; external_connection_info.target_id = extension()->id();
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc index 266e7d0..b6beff81 100644 --- a/extensions/renderer/module_system_test.cc +++ b/extensions/renderer/module_system_test.cc
@@ -316,7 +316,7 @@ .Set("name", "test") .Set("version", "1.0") .Set("manifest_version", 2) - .BuildDict(); + .Build(); return ExtensionBuilder().SetManifest(std::move(manifest)).Build(); }
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index 1a8315a..c7ae55f 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -2066,34 +2066,6 @@ ] }, { - "id": 232, - "description": "Delayed copy NV12 crashes on Intel on Windows <= 8.1.", - "cr_bugs": [727216], - "os": { - "type": "win", - "version": { - "op": "<=", - "value": "8.1" - } - }, - "vendor_id": "0x8086", - "features": [ - "disable_delayed_copy_nv12" - ] - }, - { - "id": 233, - "description": "Delayed copy NV12 displays incorrect colors on NVIDIA drivers.", - "cr_bugs": [728670], - "os": { - "type": "win" - }, - "vendor_id": "0x10de", - "features": [ - "disable_delayed_copy_nv12" - ] - }, - { "id": 235, "description": "Avoid waiting on a egl fence before pageflipping and rely on implicit sync.", "cr_bugs": [721463], @@ -2881,18 +2853,6 @@ ] }, { - "id": 308, - "cr_bugs": [983787], - "description": "Delayed copy NV12 causes crashes on GPU main thread when DXVA video decoder runs on another thread", - "os": { - "type": "win" - }, - "vendor_id": "0x1002", - "features": [ - "disable_delayed_copy_nv12" - ] - }, - { "id": 309, "cr_bugs": [993233], "description": "Don't use video processor scaling on non-Intel, non-NVIDIA GPUs.",
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt index 272a105..36324c9 100644 --- a/gpu/config/gpu_workaround_list.txt +++ b/gpu/config/gpu_workaround_list.txt
@@ -31,7 +31,6 @@ disable_d3d11 disable_d3d11_video_decoder disable_decode_swap_chain -disable_delayed_copy_nv12 disable_depth_texture disable_direct_composition disable_direct_composition_sw_video_overlays
diff --git a/headless/test/data/protocol/sanity/file-input-directory-upload.js b/headless/test/data/protocol/sanity/file-input-directory-upload.js index b0805e2..d875a2d8 100644 --- a/headless/test/data/protocol/sanity/file-input-directory-upload.js +++ b/headless/test/data/protocol/sanity/file-input-directory-upload.js
@@ -11,11 +11,7 @@ const {result} = await dp.Runtime.evaluate({ expression: `document.getElementById('file')` }); - dp.DOM.setFileInputFiles({ - objectId: result.result.objectId, - files: [dataPath] - }); - const value = await session.evaluateAsync(`new Promise(resolve => { + const valuePromise = session.evaluateAsync(`new Promise(resolve => { const file = document.getElementById('file'); async function readFile(f) { return f.name + ': ' + await f.text() + "------------------"; @@ -25,6 +21,10 @@ resolve(contents.join('\\n')); }); })`); - testRunner.log(value); + dp.DOM.setFileInputFiles({ + objectId: result.result.objectId, + files: [dataPath] + }); + testRunner.log(await valuePromise); testRunner.completeTest(); })
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc index 3d211b7..f528bb0 100644 --- a/headless/test/headless_protocol_browsertest.cc +++ b/headless/test/headless_protocol_browsertest.cc
@@ -429,7 +429,7 @@ // TODO(crbug.com/1399463) Re-enable after resolving flaky failures. HEADLESS_PROTOCOL_TEST_WITH_DATA_PATH( - DISABLED_FileInputDirectoryUpload, + FileInputDirectoryUpload, "sanity/file-input-directory-upload.js", "sanity/resources/file-input-directory-upload")
diff --git a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn index 0636231..f00a80d 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn
@@ -81,7 +81,6 @@ "//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/list_model:list_model", "//ios/chrome/browser/ui/settings:settings_root", - "//ios/chrome/browser/ui/settings:settings_root_constants", "//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/password:password_constants",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h index 6c0b403..42bd0d76 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h
@@ -48,6 +48,11 @@ // Displays the password data in edit mode without requiring any authentication. - (void)showPasswordDetailsInEditModeWithoutAuthentication; +// Remove the credential from the cache and reload password details view +// controller after a change was made. +- (void)removeCredentialFromCacheAndRefreshTableView: + (const password_manager::CredentialUIEntry&)credential; + // Delegate. @property(nonatomic, weak) id<PasswordDetailsCoordinatorDelegate> delegate;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm index 0de726eb..0201365a 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
@@ -269,6 +269,15 @@ [self.viewController showEditViewWithoutAuthentication]; } +- (void)removeCredentialFromCacheAndRefreshTableView: + (const password_manager::CredentialUIEntry&)credential { + // Remove credential from the credentials cache of the password details + // manager. + [self.mediator removeCredential:credential]; + + [self.mediator didFinishEditingPasswordDetails]; +} + - (void)onPasswordCopiedByUser { if (IsCredentialProviderExtensionPromoEnabled()) { DCHECK(_credentialProviderPromoHandler); @@ -337,8 +346,10 @@ // Notifies delegate about password deletion and records metric if needed. - (void)passwordDeletionConfirmedForCompromised:(BOOL)compromised forIndex:(int)index { - [self.delegate passwordDetailsCoordinator:self - deleteCredential:self.mediator.credentials[index]]; + [self.delegate + passwordDetailsCoordinator:self + deleteCredential:self.mediator.credentials[index] + shouldDismissView:(self.mediator.credentials.size() - 1 == 0)]; if (compromised) { base::UmaHistogramEnumeration( "PasswordManager.BulkCheck.UserAction",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h index ffea15f..ccc6011 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h
@@ -18,11 +18,14 @@ - (void)passwordDetailsCoordinatorDidRemove: (PasswordDetailsCoordinator*)coordinator; -// Called when user deleted password. This action should be handled -// outside to update the list of passwords immediately. +// Called when user deleted password. This action should be handled outside to +// update the list of passwords immediately. Callers should pass YES for +// `shouldDismiss` if this is the last password on the page, to ensure the view +// controller gets dismissed. - (void)passwordDetailsCoordinator:(PasswordDetailsCoordinator*)coordinator deleteCredential: - (const password_manager::CredentialUIEntry&)credential; + (const password_manager::CredentialUIEntry&)credential + shouldDismissView:(BOOL)shouldDismiss; @end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h index 7e53d80..404edc1 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
@@ -43,6 +43,9 @@ // Disconnects the mediator from all observers. - (void)disconnect; +// Remove credential from credentials cache. +- (void)removeCredential:(const password_manager::CredentialUIEntry&)credential; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm index a8c5822..6c7367623 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -103,19 +103,11 @@ _manager->RemoveObserver(_passwordCheckObserver.get()); } -// Update the usernames by domain dictionary by removing the old username and -// adding the new one if it has changed. -- (void)updateOldUsernameInDict:(NSString*)oldUsername - toNewUsername:(NSString*)newUsername - withSignonRealm:(NSString*)signonRealm { - if ([oldUsername isEqualToString:newUsername]) { - return; - } - - NSMutableSet* set = [_usernamesWithSameDomainDict objectForKey:signonRealm]; - if (set) { - [set removeObject:oldUsername]; - [set addObject:newUsername]; +- (void)removeCredential: + (const password_manager::CredentialUIEntry&)credential { + auto it = base::ranges::find(_credentials, credential); + if (it != _credentials.end()) { + _credentials.erase(it); } } @@ -239,4 +231,20 @@ [self.consumer setPasswords:passwords andTitle:_displayName]; } +// Update the usernames by domain dictionary by removing the old username and +// adding the new one if it has changed. +- (void)updateOldUsernameInDict:(NSString*)oldUsername + toNewUsername:(NSString*)newUsername + withSignonRealm:(NSString*)signonRealm { + if ([oldUsername isEqualToString:newUsername]) { + return; + } + + NSMutableSet* set = [_usernamesWithSameDomainDict objectForKey:signonRealm]; + if (set) { + [set removeObject:oldUsername]; + [set addObject:newUsername]; + } +} + @end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm index 5c93f0a8..7540fa0 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -24,7 +24,6 @@ #import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h" #import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" -#import "ios/chrome/browser/ui/settings/settings_root_table_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_button_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_text_edit_item_delegate.h" @@ -357,7 +356,8 @@ return item; } -- (TableViewTextButtonItem*)deleteButtonItem { +- (TableViewTextButtonItem*)deleteButtonItemForPasswordDetails: + (PasswordDetails*)passwordDetails { TableViewTextButtonItem* item = [[TableViewTextButtonItem alloc] initWithType:ItemTypeDeleteButton]; item.buttonText = l10n_util::GetNSString(IDS_IOS_SETTINGS_TOOLBAR_DELETE); @@ -365,7 +365,9 @@ item.disableButtonIntrinsicWidth = YES; item.buttonTextColor = [UIColor colorNamed:kRedColor]; item.buttonBackgroundColor = [UIColor clearColor]; - item.buttonAccessibilityIdentifier = kSettingsToolbarDeleteButtonId; + item.buttonAccessibilityIdentifier = [NSString + stringWithFormat:@"%@%@%@", kDeleteButtonForPasswordDetailsId, + passwordDetails.username, passwordDetails.password]; return item; } @@ -978,7 +980,7 @@ } if (IsPasswordGroupingEnabled() && self.tableView.editing) { - [model addItem:[self deleteButtonItem] + [model addItem:[self deleteButtonItemForPasswordDetails:passwordDetails] toSectionWithIdentifier:sectionForPassword]; } [self.passwordDetailsInfoItems addObject:passwordItem];
diff --git a/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm index eee1763b..1efb27e 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm
@@ -138,7 +138,8 @@ - (void)passwordDetailsCoordinator:(PasswordDetailsCoordinator*)coordinator deleteCredential: - (const password_manager::CredentialUIEntry&)credential { + (const password_manager::CredentialUIEntry&)credential + shouldDismissView:(BOOL)shouldDismiss { if (![self.delegate willHandlePasswordDeletion:credential]) { [self.mediator deleteCredential:credential]; }
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm index 2c442ce..ce5edf5 100644 --- a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
@@ -192,6 +192,17 @@ grey_interactable(), nullptr); } +// Matcher for the Delete button at with accessibility identifier containing +// `username` and `password` in Password Details view. +id<GREYMatcher> DeleteButtonForUsernameAndPassword(NSString* username, + NSString* password) { + return grey_allOf( + grey_accessibilityID([NSString + stringWithFormat:@"%@%@%@", kDeleteButtonForPasswordDetailsId, + username, password]), + grey_interactable(), nullptr); +} + // Matcher for the Delete button in Password Details view. id<GREYMatcher> DeleteButton() { return grey_allOf( @@ -2558,6 +2569,96 @@ assertWithMatcher:grey_notNil()]; } +// Tests that the detail view is dismissed when the last password is deleted, +// but stays if there are still passwords on the page. +- (void)testPasswordsDeletionNavigation { + if (![self groupingEnabled]) { + EARL_GREY_TEST_SKIPPED(@"This test is only for grouped passwords."); + } + + // Save forms with the same origin to be deleted later. + GREYAssert([PasswordSettingsAppInterface + saveExamplePassword:@"password1" + userName:@"user1" + origin:@"https://example1.com"], + @"Stored form was not found in the PasswordStore results."); + GREYAssert([PasswordSettingsAppInterface + saveExamplePassword:@"password2" + userName:@"user2" + origin:@"https://example1.com"], + @"Stored form was not found in the PasswordStore results."); + GREYAssert([PasswordSettingsAppInterface + saveExamplePassword:@"password3" + userName:@"user3" + origin:@"https://example3.com"], + @"Stored form was not found in the PasswordStore results."); + + OpenPasswordManager(); + + [GetInteractionForPasswordEntry(@"example1.com, 2 accounts") + assertWithMatcher:grey_notNil()]; + [GetInteractionForPasswordEntry(@"example1.com, 2 accounts") + performAction:grey_tap()]; + + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kSuccess]; + + [[EarlGrey selectElementWithMatcher:NavigationBarEditButton()] + performAction:grey_tap()]; + + // Delete first password. + [[EarlGrey selectElementWithMatcher:DeleteButtonForUsernameAndPassword( + @"user1", @"password1")] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:DeleteConfirmationButton()] + performAction:grey_tap()]; + + // Check that the current view is still the password details since there is + // still one more password left on the view. + ConditionBlock condition = ^{ + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + kPasswordDetailsTableViewId)] + assertWithMatcher:grey_notNil() + error:&error]; + return error == nil; + }; + + GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( + base::test::ios::kWaitForUIElementTimeout, condition), + @"Waiting for the view to load"); + + // Delete last password. + [[EarlGrey selectElementWithMatcher:DeleteButtonForUsernameAndPassword( + @"user2", @"password2")] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:DeleteConfirmationButton()] + performAction:grey_tap()]; + + // Check that the current view is now the password manager since we deleted + // the last password. + condition = ^{ + NSError* error = nil; + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID(kPasswordsTableViewId)] + assertWithMatcher:grey_notNil() + error:&error]; + return error == nil; + }; + + GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( + base::test::ios::kWaitForUIElementTimeout, condition), + @"Waiting for the view to load"); + + [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] + performAction:grey_tap()]; +} + @end // Rerun all the tests in this file but with kPasswordsGrouping disabled. This
diff --git a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm index bc534bc..4a6bbd75 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
@@ -272,10 +272,17 @@ - (void)passwordDetailsCoordinator:(PasswordDetailsCoordinator*)coordinator deleteCredential: - (const password_manager::CredentialUIEntry&)credential { + (const password_manager::CredentialUIEntry&)credential + shouldDismissView:(BOOL)shouldDismiss { DCHECK_EQ(self.passwordDetailsCoordinator, coordinator); [self.mediator deleteCredential:credential]; - [self.baseNavigationController popViewControllerAnimated:YES]; + + if (shouldDismiss) { + [self.baseNavigationController popViewControllerAnimated:YES]; + } else { + [self.passwordDetailsCoordinator + removeCredentialFromCacheAndRefreshTableView:credential]; + } } #pragma mark AddPasswordDetailsCoordinatorDelegate
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h index f96c42e..eae40600 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h
@@ -40,6 +40,9 @@ // displayed in the table. extern NSString* const kAddPasswordButtonId; +// Delete button accessibility identifier for Password Details. +extern NSString* const kDeleteButtonForPasswordDetailsId; + // Sections of the password settings typedef NS_ENUM(NSInteger, PasswordSectionIdentifier) { SectionIdentifierSavePasswordsSwitch = kSectionIdentifierEnumZero,
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm index d4fc352..e2bcfbd 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm
@@ -39,3 +39,6 @@ NSString* const kAddPasswordButtonId = @"addPasswordItem"; NSString* const kPasswordIssuesTableViewId = @"kPasswordIssuesTableViewId"; + +NSString* const kDeleteButtonForPasswordDetailsId = + @"kDeleteButtonForPasswordDetailsId";
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 3ac3d244..213ed63 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -986,12 +986,6 @@ #endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) #if BUILDFLAG(IS_WIN) -// Does NV12->NV12 video copy on the main thread right before the texture's -// used by GL. -BASE_FEATURE(kDelayCopyNV12Textures, - "DelayCopyNV12Textures", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enables DirectShow GetPhotoState implementation // Created to act as a kill switch by disabling it, in the case of the // resurgence of https://crbug.com/722038
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index f59a686..b24cd08 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -308,7 +308,6 @@ #endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) #if BUILDFLAG(IS_WIN) -MEDIA_EXPORT BASE_DECLARE_FEATURE(kDelayCopyNV12Textures); MEDIA_EXPORT BASE_DECLARE_FEATURE(kDirectShowGetPhotoState); MEDIA_EXPORT BASE_DECLARE_FEATURE(kIncludeIRCamerasInDeviceEnumeration); MEDIA_EXPORT BASE_DECLARE_FEATURE(kMediaFoundationVideoCapture);
diff --git a/media/formats/webm/webm_video_client.cc b/media/formats/webm/webm_video_client.cc index b9add5a..9342e6e 100644 --- a/media/formats/webm/webm_video_client.cc +++ b/media/formats/webm/webm_video_client.cc
@@ -5,6 +5,7 @@ #include "media/formats/webm/webm_video_client.h" #include "media/base/video_decoder_config.h" +#include "media/formats/mp4/box_definitions.h" #include "media/formats/webm/webm_constants.h" #include "media/media_buildflags.h" @@ -28,6 +29,22 @@ static_cast<size_t>(VP9PROFILE_PROFILE0) + data[2]); } +#if BUILDFLAG(ENABLE_AV1_DECODER) +media::VideoCodecProfile GetAV1CodecProfile(const std::vector<uint8_t>& data) { + if (data.empty()) { + return AV1PROFILE_PROFILE_MAIN; + } + + mp4::AV1CodecConfigurationRecord av1_config; + if (av1_config.Parse(data.data(), data.size())) { + return av1_config.profile; + } + + DLOG(WARNING) << "Failed to parser AV1 extra data for profile."; + return AV1PROFILE_PROFILE_MAIN; +} +#endif // BUILDFLAG(ENABLE_AV1_DECODER) + // Values for "StereoMode" are spec'd here: // https://www.matroska.org/technical/elements.html#StereoMode bool IsValidStereoMode(int64_t stereo_mode_code) { @@ -92,11 +109,8 @@ config->hdr_metadata().has_value() || !is_8bit); #if BUILDFLAG(ENABLE_AV1_DECODER) } else if (codec_id == "V_AV1") { - // TODO(dalecurtis): AV1 profiles in WebM are not finalized, this needs - // updating to read the actual profile and configuration before enabling for - // release. http://crbug.com/784993 video_codec = VideoCodec::kAV1; - profile = AV1PROFILE_PROFILE_MAIN; + profile = GetAV1CodecProfile(codec_private); #endif } else { MEDIA_LOG(ERROR, media_log_) << "Unsupported video codec_id " << codec_id;
diff --git a/media/formats/webm/webm_video_client_unittest.cc b/media/formats/webm/webm_video_client_unittest.cc index dd91182..a8de5a6 100644 --- a/media/formats/webm/webm_video_client_unittest.cc +++ b/media/formats/webm/webm_video_client_unittest.cc
@@ -162,6 +162,31 @@ << expected_config.AsHumanReadableString() << ")"; } +#if BUILDFLAG(ENABLE_AV1_DECODER) +TEST_F(WebMVideoClientTest, InitializeConfigAV1Profile) { + const std::string codec_id = "V_AV1"; + const auto expected_profile = AV1PROFILE_PROFILE_HIGH; + const std::vector<uint8_t> codec_private{0x81, 0x20, 0x00, 0x00, 0x0a, 0x0a, + 0x20, 0x00, 0x00, 0x03, 0xbf, 0x7f, + 0x7b, 0xff, 0xf3, 0x04}; + + VideoDecoderConfig config; + EXPECT_TRUE(webm_video_client_.InitializeConfig(codec_id, codec_private, + EncryptionScheme(), &config)); + + VideoDecoderConfig expected_config( + VideoCodec::kAV1, expected_profile, + VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace::REC709(), + kNoTransformation, kCodedSize, gfx::Rect(kCodedSize), kCodedSize, + codec_private, EncryptionScheme::kUnencrypted); + + EXPECT_TRUE(config.Matches(expected_config)) + << "Config (" << config.AsHumanReadableString() + << ") does not match expected (" + << expected_config.AsHumanReadableString() << ")"; +} +#endif + TEST_F(WebMVideoClientTest, InvalidStereoMode) { EXPECT_MEDIA_LOG(UnexpectedStereoMode()); OnUInt(kWebMIdStereoMode, 15);
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc index ffecc9f..855013e 100644 --- a/media/gpu/android/media_codec_video_decoder.cc +++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -142,21 +142,25 @@ if (device_info->IsAv1DecoderAvailable()) { if (device_info->IsDecoderKnownUnaccelerated(VideoCodec::kAV1)) { - supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX, - gfx::Size(0, 0), gfx::Size(3840, 2160), + supported_configs.emplace_back(AV1PROFILE_PROFILE_MAIN, + AV1PROFILE_PROFILE_MAIN, gfx::Size(0, 0), + gfx::Size(3840, 2160), true, // allow_encrypted true); // require_encrypted - supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX, - gfx::Size(0, 0), gfx::Size(2160, 3840), + supported_configs.emplace_back(AV1PROFILE_PROFILE_MAIN, + AV1PROFILE_PROFILE_MAIN, gfx::Size(0, 0), + gfx::Size(2160, 3840), true, // allow_encrypted true); // require_encrypted } else { - supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX, - gfx::Size(0, 0), gfx::Size(3840, 2160), + supported_configs.emplace_back(AV1PROFILE_PROFILE_MAIN, + AV1PROFILE_PROFILE_MAIN, gfx::Size(0, 0), + gfx::Size(3840, 2160), true, // allow_encrypted false); // require_encrypted - supported_configs.emplace_back(AV1PROFILE_MIN, AV1PROFILE_MAX, - gfx::Size(0, 0), gfx::Size(2160, 3840), + supported_configs.emplace_back(AV1PROFILE_PROFILE_MAIN, + AV1PROFILE_PROFILE_MAIN, gfx::Size(0, 0), + gfx::Size(2160, 3840), true, // allow_encrypted false); // require_encrypted }
diff --git a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc index 06815fded..0158342 100644 --- a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc +++ b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc
@@ -181,8 +181,8 @@ return nullptr; } - if (!(permissions & PROT_READ && permissions & PROT_WRITE)) { - LOG(ERROR) << "VAAPI DMA Buffer must be mapped read/write."; + if (!(permissions & PROT_READ)) { + LOG(ERROR) << "VAAPI DMA Buffer must be mapped with read permissions."; return nullptr; }
diff --git a/media/gpu/windows/dxva_picture_buffer_win.cc b/media/gpu/windows/dxva_picture_buffer_win.cc index 9ff15bc..b49270a 100644 --- a/media/gpu/windows/dxva_picture_buffer_win.cc +++ b/media/gpu/windows/dxva_picture_buffer_win.cc
@@ -39,15 +39,6 @@ return picture_buffer; } - case DXVAVideoDecodeAccelerator::PictureBufferMechanism:: - DELAYED_COPY_TO_NV12: { - auto picture_buffer = - std::make_unique<EGLStreamDelayedCopyPictureBuffer>(buffer); - if (!picture_buffer->Initialize(decoder)) - return nullptr; - - return picture_buffer; - } case DXVAVideoDecodeAccelerator::PictureBufferMechanism::COPY_TO_NV12: { auto picture_buffer = std::make_unique<EGLStreamCopyPictureBuffer>(buffer); @@ -476,121 +467,6 @@ return true; } -EGLStreamDelayedCopyPictureBuffer::EGLStreamDelayedCopyPictureBuffer( - const PictureBuffer& buffer) - : DXVAPictureBuffer(buffer), stream_(nullptr) {} - -EGLStreamDelayedCopyPictureBuffer::~EGLStreamDelayedCopyPictureBuffer() { - // stream_ will be deleted by gl_image_. -} - -bool EGLStreamDelayedCopyPictureBuffer::Initialize( - const DXVAVideoDecodeAccelerator& decoder) { - RETURN_ON_FAILURE(picture_buffer_.service_texture_ids().size() >= 2, - "Not enough texture ids provided", false); - - EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(); - const EGLint stream_attributes[] = { - EGL_CONSUMER_LATENCY_USEC_KHR, - 0, - EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, - 0, - EGL_NONE, - }; - stream_ = eglCreateStreamKHR(egl_display, stream_attributes); - RETURN_ON_FAILURE(!!stream_, "Could not create stream", false); - gl::ScopedActiveTexture texture0(GL_TEXTURE0); - gl::ScopedTextureBinder texture0_binder( - GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[0]); - gl::ScopedActiveTexture texture1(GL_TEXTURE1); - gl::ScopedTextureBinder texture1_binder( - GL_TEXTURE_EXTERNAL_OES, picture_buffer_.service_texture_ids()[1]); - - EGLAttrib consumer_attributes[] = { - EGL_COLOR_BUFFER_TYPE, - EGL_YUV_BUFFER_EXT, - EGL_YUV_NUMBER_OF_PLANES_EXT, - 2, - EGL_YUV_PLANE0_TEXTURE_UNIT_NV, - 0, - EGL_YUV_PLANE1_TEXTURE_UNIT_NV, - 1, - EGL_NONE, - }; - EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV( - egl_display, stream_, consumer_attributes); - RETURN_ON_FAILURE(result, "Could not set stream consumer", false); - - EGLAttrib producer_attributes[] = { - EGL_NONE, - }; - - result = eglCreateStreamProducerD3DTextureANGLE(egl_display, stream_, - producer_attributes); - RETURN_ON_FAILURE(result, "Could not create stream producer", false); - scoped_refptr<CopyingGLImageEGLStream> copying_image_ = - base::MakeRefCounted<CopyingGLImageEGLStream>( - ComD3D11Device(decoder.D3D11Device()), size(), stream_); - gl_image_ = copying_image_; - return copying_image_->Initialize(); -} - -bool EGLStreamDelayedCopyPictureBuffer::ReusePictureBuffer() { - DCHECK_NE(UNUSED, state_); - - static_cast<CopyingGLImageEGLStream*>(gl_image_.get())->UnbindFromTexture(); - if (current_d3d_sample_) { - dx11_decoding_texture_.Reset(); - current_d3d_sample_.Reset(); - } - state_ = UNUSED; - return true; -} - -bool EGLStreamDelayedCopyPictureBuffer::BindSampleToTexture( - DXVAVideoDecodeAccelerator* decoder, - Microsoft::WRL::ComPtr<IMFSample> sample) { - DCHECK_EQ(BOUND, state_); - state_ = IN_CLIENT; - - current_d3d_sample_ = sample; - - Microsoft::WRL::ComPtr<IMFMediaBuffer> output_buffer; - HRESULT hr = current_d3d_sample_->GetBufferByIndex(0, &output_buffer); - RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); - - Microsoft::WRL::ComPtr<IMFDXGIBuffer> dxgi_buffer; - hr = output_buffer.As(&dxgi_buffer); - RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample", - false); - hr = dxgi_buffer->GetResource(IID_PPV_ARGS(&dx11_decoding_texture_)); - RETURN_ON_HR_FAILURE(hr, "Failed to get texture from output sample", false); - UINT subresource; - dxgi_buffer->GetSubresourceIndex(&subresource); - if (!decoder->InitializeID3D11VideoProcessor(size().width(), size().height(), - color_space_)) - return false; - - DCHECK(decoder->d3d11_processor_); - DCHECK(decoder->enumerator_); - - CopyingGLImageEGLStream* copying_gl_image = - static_cast<CopyingGLImageEGLStream*>(gl_image_.get()); - DCHECK(copying_gl_image); - - copying_gl_image->SetTexture(dx11_decoding_texture_, subresource); - return copying_gl_image->InitializeVideoProcessor(decoder->d3d11_processor_, - decoder->enumerator_); -} - -bool EGLStreamDelayedCopyPictureBuffer::AllowOverlay() const { - return true; -} - -bool EGLStreamDelayedCopyPictureBuffer::CanBindSamples() const { - return true; -} - EGLStreamCopyPictureBuffer::EGLStreamCopyPictureBuffer( const PictureBuffer& buffer) : DXVAPictureBuffer(buffer), stream_(nullptr) {}
diff --git a/media/gpu/windows/dxva_picture_buffer_win.h b/media/gpu/windows/dxva_picture_buffer_win.h index e3c5783..fed9960 100644 --- a/media/gpu/windows/dxva_picture_buffer_win.h +++ b/media/gpu/windows/dxva_picture_buffer_win.h
@@ -204,26 +204,6 @@ ComD3D11Texture2D dx11_decoding_texture_; }; -// Shares the decoded texture with ANGLE without copying by using an EGL stream. -class EGLStreamDelayedCopyPictureBuffer : public DXVAPictureBuffer { - public: - explicit EGLStreamDelayedCopyPictureBuffer(const PictureBuffer& buffer); - ~EGLStreamDelayedCopyPictureBuffer() override; - - bool Initialize(const DXVAVideoDecodeAccelerator& decoder); - bool ReusePictureBuffer() override; - bool BindSampleToTexture(DXVAVideoDecodeAccelerator* decoder, - Microsoft::WRL::ComPtr<IMFSample> sample) override; - bool AllowOverlay() const override; - bool CanBindSamples() const override; - - private: - EGLStreamKHR stream_; - - Microsoft::WRL::ComPtr<IMFSample> current_d3d_sample_; - ComD3D11Texture2D dx11_decoding_texture_; -}; - // Creates an NV12 texture and copies to it, then shares that with ANGLE. class EGLStreamCopyPictureBuffer : public DXVAPictureBuffer { public:
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index 05efd05..1c714c6 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -668,9 +668,6 @@ : kNumPictureBuffers), support_copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video && !workarounds.disable_nv12_dxgi_video), - support_delayed_copy_nv12_textures_( - base::FeatureList::IsEnabled(kDelayCopyNV12Textures) && - !workarounds.disable_delayed_copy_nv12), use_dx11_(false), use_keyed_mutex_(false), using_angle_device_(false), @@ -1232,16 +1229,6 @@ RETURN_AND_NOTIFY_ON_FAILURE(it->second->ReusePictureBuffer(), "Failed to reuse picture buffer", PLATFORM_FAILURE, ); - if (bind_image_cb_ && (GetPictureBufferMechanism() == - PictureBufferMechanism::DELAYED_COPY_TO_NV12)) { - // Unbind the image to ensure it will be copied again the next time it's - // needed. - for (uint32_t client_id : - it->second->picture_buffer().client_texture_ids()) { - bind_image_cb_.Run(client_id, GetTextureTarget(), - it->second->gl_image()); - } - } ProcessPendingSamples(); if (pending_flush_) { @@ -2987,9 +2974,7 @@ // If we're copying textures or just not using color space information, set // the same color space on input and output. if ((!use_color_info_ && !use_fp16_) || - GetPictureBufferMechanism() == PictureBufferMechanism::COPY_TO_NV12 || - GetPictureBufferMechanism() == - PictureBufferMechanism::DELAYED_COPY_TO_NV12) { + GetPictureBufferMechanism() == PictureBufferMechanism::COPY_TO_NV12) { const auto d3d11_color_space = gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space); video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.Get(), @@ -3196,7 +3181,6 @@ uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { switch (GetPictureBufferMechanism()) { case PictureBufferMechanism::BIND: - case PictureBufferMechanism::DELAYED_COPY_TO_NV12: case PictureBufferMechanism::COPY_TO_NV12: return GL_TEXTURE_EXTERNAL_OES; case PictureBufferMechanism::COPY_TO_RGB: @@ -3330,8 +3314,6 @@ // It works fine dealing P010/P016 with BIND mode. if (support_share_nv12_textures_ || decoder_output_p010_or_p016_) return PictureBufferMechanism::BIND; - if (support_delayed_copy_nv12_textures_ && support_copy_nv12_textures_) - return PictureBufferMechanism::DELAYED_COPY_TO_NV12; if (support_copy_nv12_textures_) return PictureBufferMechanism::COPY_TO_NV12; return PictureBufferMechanism::COPY_TO_RGB; @@ -3340,7 +3322,6 @@ bool DXVAVideoDecodeAccelerator::ShouldUseANGLEDevice() const { switch (GetPictureBufferMechanism()) { case PictureBufferMechanism::BIND: - case PictureBufferMechanism::DELAYED_COPY_TO_NV12: return true; case PictureBufferMechanism::COPY_TO_NV12: case PictureBufferMechanism::COPY_TO_RGB:
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.h b/media/gpu/windows/dxva_video_decode_accelerator_win.h index 78c5d8c7..3c6ea509 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.h +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.h
@@ -149,8 +149,8 @@ // Bind the resulting GLImage to the NV12 texture. If the texture's used // in a an overlay than use it directly, otherwise copy it to another NV12 - // texture when necessary. - DELAYED_COPY_TO_NV12 = 2, + // texture when necessary -- no longer used + // DELAYED_COPY_TO_NV12 = 2, // Bind the NV12 decoder texture directly to the texture used in ANGLE. BIND = 3, @@ -553,9 +553,6 @@ // ANGLE. bool support_copy_nv12_textures_; - // Supports copying NV12 textures on the main thread to use in ANGLE. - bool support_delayed_copy_nv12_textures_; - // Copy video to FP16 scRGB textures. bool use_fp16_ = false;
diff --git a/media/gpu/windows/gl_image_egl_stream.cc b/media/gpu/windows/gl_image_egl_stream.cc index 85eb127..6346f39 100644 --- a/media/gpu/windows/gl_image_egl_stream.cc +++ b/media/gpu/windows/gl_image_egl_stream.cc
@@ -64,132 +64,4 @@ } } -CopyingGLImageEGLStream::CopyingGLImageEGLStream( - const Microsoft::WRL::ComPtr<ID3D11Device>& d3d11_device, - const gfx::Size& size, - EGLStreamKHR stream) - : GLImageEGLStream(size, stream), d3d11_device_(d3d11_device) {} - -bool CopyingGLImageEGLStream::Initialize() { - D3D11_TEXTURE2D_DESC desc; - desc.Width = size_.width(); - desc.Height = size_.height(); - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_NV12; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT hr = - d3d11_device_->CreateTexture2D(&desc, nullptr, &decoder_copy_texture_); - if (FAILED(hr)) { - DLOG(ERROR) << "CreateTexture2D failed: " << std::hex << hr; - return false; - } - EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(); - - EGLAttrib frame_attributes[] = { - EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, - 0, - EGL_NONE, - }; - - EGLBoolean result = eglStreamPostD3DTextureANGLE( - egl_display, stream_, static_cast<void*>(decoder_copy_texture_.Get()), - frame_attributes); - if (!result) { - DLOG(ERROR) << "eglStreamPostD3DTextureANGLE failed"; - return false; - } - result = eglStreamConsumerAcquireKHR(egl_display, stream_); - if (!result) { - DLOG(ERROR) << "eglStreamConsumerAcquireKHR failed"; - return false; - } - - d3d11_device_.As(&video_device_); - Microsoft::WRL::ComPtr<ID3D11DeviceContext> context; - d3d11_device_->GetImmediateContext(&context); - context.As(&video_context_); - -#if DCHECK_IS_ON() - Microsoft::WRL::ComPtr<ID3D10Multithread> multithread; - d3d11_device_.As(&multithread); - DCHECK(multithread->GetMultithreadProtected()); -#endif // DCHECK_IS_ON() - - return true; -} - -bool CopyingGLImageEGLStream::InitializeVideoProcessor( - const Microsoft::WRL::ComPtr<ID3D11VideoProcessor>& video_processor, - const Microsoft::WRL::ComPtr<ID3D11VideoProcessorEnumerator>& enumerator) { - output_view_.Reset(); - - Microsoft::WRL::ComPtr<ID3D11Device> processor_device; - video_processor->GetDevice(&processor_device); - DCHECK_EQ(d3d11_device_.Get(), processor_device.Get()); - - d3d11_processor_ = video_processor; - enumerator_ = enumerator; - D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = { - D3D11_VPOV_DIMENSION_TEXTURE2D}; - output_view_desc.Texture2D.MipSlice = 0; - Microsoft::WRL::ComPtr<ID3D11VideoProcessorOutputView> output_view; - HRESULT hr = video_device_->CreateVideoProcessorOutputView( - decoder_copy_texture_.Get(), enumerator_.Get(), &output_view_desc, - &output_view_); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to get output view"; - return false; - } - return true; -} - -void CopyingGLImageEGLStream::UnbindFromTexture() { - copied_ = false; -} - -bool CopyingGLImageEGLStream::BindTexImage(unsigned target) { - if (copied_) { - return true; - } - - DCHECK(video_device_); - Microsoft::WRL::ComPtr<ID3D11Device> texture_device; - texture_->GetDevice(&texture_device); - DCHECK_EQ(d3d11_device_.Get(), texture_device.Get()); - - D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0}; - input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; - input_view_desc.Texture2D.ArraySlice = (UINT)level_; - input_view_desc.Texture2D.MipSlice = 0; - Microsoft::WRL::ComPtr<ID3D11VideoProcessorInputView> input_view; - HRESULT hr = video_device_->CreateVideoProcessorInputView( - texture_.Get(), enumerator_.Get(), &input_view_desc, &input_view); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to create video processor input view."; - return false; - } - - D3D11_VIDEO_PROCESSOR_STREAM streams = {0}; - streams.Enable = TRUE; - streams.pInputSurface = input_view.Get(); - - hr = video_context_->VideoProcessorBlt(d3d11_processor_.Get(), - output_view_.Get(), 0, 1, &streams); - if (FAILED(hr)) { - DLOG(ERROR) << "Failed to process video"; - return false; - } - copied_ = true; - return true; -} - -CopyingGLImageEGLStream::~CopyingGLImageEGLStream() = default; - } // namespace media
diff --git a/media/gpu/windows/gl_image_egl_stream.h b/media/gpu/windows/gl_image_egl_stream.h index 4b9404e..61e2c5ae 100644 --- a/media/gpu/windows/gl_image_egl_stream.h +++ b/media/gpu/windows/gl_image_egl_stream.h
@@ -48,37 +48,6 @@ size_t level_ = 0; }; -// This copies to a new texture on bind. -class CopyingGLImageEGLStream : public GLImageEGLStream { - public: - CopyingGLImageEGLStream( - const Microsoft::WRL::ComPtr<ID3D11Device>& d3d11_device, - const gfx::Size& size, - EGLStreamKHR stream); - - bool Initialize(); - bool InitializeVideoProcessor( - const Microsoft::WRL::ComPtr<ID3D11VideoProcessor>& video_processor, - const Microsoft::WRL::ComPtr<ID3D11VideoProcessorEnumerator>& enumerator); - void UnbindFromTexture(); - - // GLImage implementation. - bool BindTexImage(unsigned target) override; - - private: - ~CopyingGLImageEGLStream() override; - - bool copied_ = false; - - Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device_; - Microsoft::WRL::ComPtr<ID3D11VideoContext> video_context_; - Microsoft::WRL::ComPtr<ID3D11VideoProcessor> d3d11_processor_; - Microsoft::WRL::ComPtr<ID3D11VideoProcessorEnumerator> enumerator_; - Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_; - Microsoft::WRL::ComPtr<ID3D11Texture2D> decoder_copy_texture_; - Microsoft::WRL::ComPtr<ID3D11VideoProcessorOutputView> output_view_; -}; - } // namespace media #endif // MEDIA_GPU_WINDOWS_GL_IMAGE_EGL_STREAM_H_
diff --git a/media/video/gpu_video_accelerator_factories.h b/media/video/gpu_video_accelerator_factories.h index beb43bd2..eb08a3bd 100644 --- a/media/video/gpu_video_accelerator_factories.h +++ b/media/video/gpu_video_accelerator_factories.h
@@ -160,6 +160,9 @@ // May be called on any thread. virtual void NotifyEncoderSupportKnown(base::OnceClosure callback) = 0; + // Caller owns returned pointer, but should call Destroy() on it (instead of + // directly deleting) for proper destruction, as per the + // VideoEncodeAccelerator interface. virtual std::unique_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator() = 0;
diff --git a/media/video/video_encode_accelerator.h b/media/video/video_encode_accelerator.h index f37a1d50..61a515a0 100644 --- a/media/video/video_encode_accelerator.h +++ b/media/video/video_encode_accelerator.h
@@ -456,7 +456,7 @@ virtual bool IsGpuFrameResizeSupported(); protected: - // Do not delete directly; use Destroy() or own it with a unique_ptr, which + // Do not delete directly; use Destroy() or own it with a scoped_ptr, which // will Destroy() it properly by default. virtual ~VideoEncodeAccelerator(); };
diff --git a/net/cert/pki/parsed_certificate.h b/net/cert/pki/parsed_certificate.h index fe4414e3..5fba2b80 100644 --- a/net/cert/pki/parsed_certificate.h +++ b/net/cert/pki/parsed_certificate.h
@@ -302,7 +302,8 @@ std::vector<std::string_view> ca_issuers_uris_; std::vector<std::string_view> ocsp_uris_; - // Policies extension. + // Policies extension. This list will already have been checked for + // duplicates. bool has_policy_oids_ = false; std::vector<der::Input> policy_oids_;
diff --git a/net/cert/pki/verify_certificate_chain.cc b/net/cert/pki/verify_certificate_chain.cc index d84ed652..1957a9a 100644 --- a/net/cert/pki/verify_certificate_chain.cc +++ b/net/cert/pki/verify_certificate_chain.cc
@@ -5,6 +5,7 @@ #include "net/cert/pki/verify_certificate_chain.h" #include <algorithm> +#include <cassert> #include "net/cert/pki/cert_error_params.h" #include "net/cert/pki/cert_errors.h" @@ -16,7 +17,6 @@ #include "net/cert/pki/trust_store.h" #include "net/cert/pki/verify_signed_data.h" #include "net/der/input.h" -#include "net/der/parser.h" namespace net { @@ -359,196 +359,265 @@ } } -// Returns |true| if |policies| contains the OID |search_oid|. -bool SetContains(const std::set<der::Input>& policies, - const der::Input& search_oid) { - return policies.count(search_oid) > 0; -} - // Representation of RFC 5280's "valid_policy_tree", used to keep track of the -// valid policies and policy re-mappings. +// valid policies and policy re-mappings. This structure is defined in +// section 6.1.2. // -// ValidPolicyTree differs slightly from RFC 5280's description in that: +// ValidPolicyGraph differs from RFC 5280's description in that: // // (1) It does not track "qualifier_set". This is not needed as it is not // output by this implementation. // -// (2) It only stores the most recent level of the policy tree rather than -// the full tree of nodes. -class ValidPolicyTree { +// (2) It builds a directed acyclic graph, rather than a tree. When a given +// policy matches multiple parents, RFC 5280 makes a separate node for +// each parent. This representation condenses them into one node with +// multiple parents. +// +// (3) It does not track "expected_policy_set" or anyPolicy nodes directly. +// Rather it maintains, only for the most recent level, whether there is an +// anyPolicy node and an inverted map of all "expected_policy_set" values. +// +// (4) Some pruning steps are deferred to when policies are evaluated, as a +// reachability pass. +class ValidPolicyGraph { public: - ValidPolicyTree() = default; + ValidPolicyGraph() = default; - ValidPolicyTree(const ValidPolicyTree&) = delete; - ValidPolicyTree& operator=(const ValidPolicyTree&) = delete; + ValidPolicyGraph(const ValidPolicyGraph&) = delete; + ValidPolicyGraph& operator=(const ValidPolicyGraph&) = delete; + // A Node is an entry in the policy graph. It contains information about some + // policy asserted by a certificate in the chain. The policy OID itself is + // omitted because it is the key in the Level map. struct Node { - // |root_policy| is equivalent to |valid_policy|, but in the domain of the - // caller. + // The list of "valid_policy" values for all nodes which are a parent of + // this node, other than anyPolicy. If empty, this node has a single parent, + // anyPolicy. // - // The reason for this distinction is the Policy Mappings extension. + // Nodes whose parent is anyPolicy are root policies, and may be returned + // in the authorities-constrained-policy-set. Nodes with a concrete policy + // as a parent are derived from that policy in the issuer certificate, + // possibly with a policy mapping applied. // - // So whereas |valid_policy| is in the remapped domain defined by the - // issuing certificate, |root_policy| is in the fixed domain of the caller. - // - // OIDs in "user_initial_policy_set" and "user_constrained_policy_set" are - // directly comparable to |root_policy| values, but not necessarily to - // |valid_policy|. - // - // In terms of the valid policy tree, |root_policy| can be found by - // starting at the node's root ancestor, and finding the first node with a - // valid_policy other than anyPolicy. This is effectively the same process - // as used during policy tree intersection in RFC 5280 6.1.5.g.iii.1 - der::Input root_policy; + // Note it is not possible for a policy to have both anyPolicy and a + // concrete policy as a parent. Section 6.1.3, step d.1.ii only runs if + // there was no match in step d.1.i. + std::vector<der::Input> parent_policies; - // The same as RFC 5280's "valid_policy" variable. - der::Input valid_policy; + // Whether this node matches a policy mapping in the certificate. If true, + // its "expected_policy_set" comes from the policy mappings extension. If + // false, its "expected_policy_set" is itself. + bool mapped = false; - // The same as RFC 5280s "expected_policy_set" variable. - std::set<der::Input> expected_policy_set; - - // Note that RFC 5280's "qualifier_set" is omitted. + // Whether this node is reachable from some valid policy in the end-entity + // certificate. Computed during GetValidRootPolicySet(). + bool reachable = false; }; - // Level represents all the nodes at depth "i" in the valid_policy_tree. - using Level = std::vector<Node>; + // The policy graph is organized into "levels", each corresponding to a + // certificate in the chain. We maintain a map from "valid_policy" to the + // corresponding Node. This is the set of policies asserted by this + // certificate. The special anyPolicy OID is handled separately below. + using Level = std::map<der::Input, Node>; - // Initializes the ValidPolicyTree for the given "user_initial_policy_set". + // Additional per-level information that only needs to be maintained for the + // bottom-most level. + struct LevelDetails { + // Maintains the "expected_policy_set" values for nodes in a level of the + // graph, but the map is inverted from RFC 5280's formulation. For a given + // policy OID P, other than anyPolicy, this map gives the set of nodes where + // P appears in the node's "expected_policy_set". anyPolicy is handled + // separately below. + std::map<der::Input, std::vector<der::Input>> expected_policy_map; + + // Whether there is a node at this level whose "valid_policy" is anyPolicy. + // + // Note anyPolicy's "expected_policy_set" always {anyPolicy}, and anyPolicy + // will never appear in the "expected_policy_set" of any other policy. That + // means this field also captures how anyPolicy appears in + // "expected_policy_set". + bool has_any_policy = false; + }; + + // Initializes the ValidPolicyGraph for the given "user_initial_policy_set". // - // In RFC 5280, the valid_policy_tree is initialized to a root node at depth + // In RFC 5280, the valid_policy_tree is initialized to a root node at level // 0 of "anyPolicy"; the intersection with the "user_initial_policy_set" is // done at the end (Wrap Up) as described in section 6.1.5 step g. // // Whereas in this implementation, the restriction on policies is added here, - // and intersecting the valid policy tree during Wrap Up is no longer needed. + // and intersecting during Wrap Up is no longer needed. // // The final "user_constrained_policy_set" obtained will be the same. The // advantages of this approach is simpler code. - void Init(const std::set<der::Input>& user_initial_policy_set) { - Clear(); - for (const der::Input& policy_oid : user_initial_policy_set) - AddRootNode(policy_oid); + // + // TODO(davidben): It is not quite the same in some edge cases around + // anyPolicy. Switch this to match RFC 5280's formulation. + void Init(const std::set<der::Input>& user_constained_policy_set) { + SetNull(); + StartLevel(); + for (der::Input policy : user_constained_policy_set) { + if (policy == der::Input(kAnyPolicyOid)) { + AddAnyPolicyNode(); + } else { + AddNode(policy, {}); + } + } } - // Returns the current level (i.e. all nodes at depth i in the valid - // policy tree). - const Level& current_level() const { return current_level_; } - Level& current_level() { return current_level_; } - // In RFC 5280 valid_policy_tree may be set to null. That is represented here // by emptiness. - bool IsNull() const { return current_level_.empty(); } - void SetNull() { Clear(); } + bool IsNull() const { + return !current_level_.has_any_policy && + (levels_.empty() || levels_.back().empty()); + } + void SetNull() { + levels_.clear(); + current_level_ = LevelDetails{}; + } - // This implementation keeps only the last level of the valid policy - // tree. Calling StartLevel() returns the nodes for the previous - // level, and starts a new level. - Level StartLevel() { - Level prev_level; - std::swap(prev_level, current_level_); + // Completes the previous level, returning a corresponding LevelDetails + // structure, and starts a new level. + LevelDetails StartLevel() { + // Finish building expected_policy_map for the previous level. + if (!levels_.empty()) { + for (const auto& [policy, node] : levels_.back()) { + if (!node.mapped) { + current_level_.expected_policy_map[policy].push_back(policy); + } + } + } + + LevelDetails prev_level = std::move(current_level_); + levels_.emplace_back(); + current_level_ = LevelDetails{}; return prev_level; } // Gets the set of policies (in terms of root authority's policy domain) that - // are valid at the curent level of the policy tree. + // are valid at the bottom level of the policy graph. This is what X.509 calls + // "user-constrained-policy-set". // - // For example: - // - // * If the valid policy tree was initialized with anyPolicy, then this - // function returns what X.509 calls "authorities-constrained-policy-set". - // - // * If the valid policy tree was instead initialized with the - // "user-initial-policy_set", then this function returns what X.509 - // calls "user-constrained-policy-set" - // ("authorities-constrained-policy-set" intersected with the - // "user-initial-policy-set"). + // This method may only be called once, after the policy graph is constructed. void GetValidRootPolicySet(std::set<der::Input>* policy_set) { policy_set->clear(); - for (const Node& node : current_level_) - policy_set->insert(node.root_policy); + if (levels_.empty()) { + return; + } - // If the result includes anyPolicy, simplify it to a set of size 1. - if (policy_set->size() > 1 && - SetContains(*policy_set, der::Input(kAnyPolicyOid))) { + if (current_level_.has_any_policy) { *policy_set = {der::Input(kAnyPolicyOid)}; + return; } - } - // Adds a node |n| to the current level which is a child of |parent| - // such that: - // * n.valid_policy = policy_oid - // * n.expected_policy_set = {policy_oid} - void AddNode(const Node& parent, const der::Input& policy_oid) { - AddNodeWithExpectedPolicySet(parent, policy_oid, {policy_oid}); - } - - // Adds a node |n| to the current level which is a child of |parent| - // such that: - // * n.valid_policy = policy_oid - // * n.expected_policy_set = expected_policy_set - void AddNodeWithExpectedPolicySet( - const Node& parent, - const der::Input& policy_oid, - const std::set<der::Input>& expected_policy_set) { - Node new_node; - new_node.valid_policy = policy_oid; - new_node.expected_policy_set = expected_policy_set; - - // Consider the root policy as the first policy other than anyPolicy (or - // anyPolicy if it hasn't been restricted yet). - new_node.root_policy = (parent.root_policy == der::Input(kAnyPolicyOid)) - ? policy_oid - : parent.root_policy; - - current_level_.push_back(std::move(new_node)); - } - - // Returns the first node having valid_policy == anyPolicy in |level|, or - // nullptr if there is none. - static const Node* FindAnyPolicyNode(const Level& level) { - for (const Node& node : level) { - if (node.valid_policy == der::Input(kAnyPolicyOid)) - return &node; + // The root's policy domain is determined by nodes with anyPolicy as a + // parent. However, we must limit to those which are reachable from the + // end-entity certificate because we defer some pruning steps. + for (auto& [policy, node] : levels_.back()) { + node.reachable = true; } - return nullptr; - } - - // Deletes all nodes |n| in |level| where |n.valid_policy| matches the given - // |valid_policy|. This may re-order the nodes in |level|. - static void DeleteNodesMatchingValidPolicy(const der::Input& valid_policy, - Level* level) { - // This works by swapping nodes to the end of the vector, and then doing a - // single resize to delete them all. - auto cur = level->begin(); - auto end = level->end(); - while (cur != end) { - bool should_delete_node = cur->valid_policy == valid_policy; - if (should_delete_node) { - end = std::prev(end); - if (cur != end) - std::iter_swap(cur, end); - } else { - ++cur; + for (size_t i = levels_.size() - 1; i < levels_.size(); i--) { + for (auto& [policy, node] : levels_[i]) { + if (!node.reachable) { + continue; + } + if (node.parent_policies.empty()) { + // |node|'s parent is anyPolicy, so this is in the root policy domain. + policy_set->insert(policy); + } else if (i > 0) { + // Otherwise, continue searching the previous level. + for (der::Input parent : node.parent_policies) { + auto iter = levels_[i - 1].find(parent); + if (iter != levels_[i - 1].end()) { + iter->second.reachable = true; + } + } + } } } - level->erase(end, level->end()); + } + + // Adds a node with policy anyPolicy to the current level. + void AddAnyPolicyNode() { + assert(!levels_.empty()); + current_level_.has_any_policy = true; + } + + // Adds a node to the current level which is a child of |parent_policies| with + // the specified policy. + void AddNode(der::Input policy, std::vector<der::Input> parent_policies) { + assert(policy != der::Input(kAnyPolicyOid)); + AddNodeReturningIterator(policy, std::move(parent_policies)); + } + + // Adds a node to the current level which is a child of anyPolicy with the + // specified policy. + void AddNodeWithParentAnyPolicy(der::Input policy) { + // An empty parent set represents a node parented by anyPolicy. + AddNode(policy, {}); + } + + // Maps |issuer_policy| to |subject_policy|, as in RFC 5280, section 6.1.4, + // step b.1. + void AddPolicyMapping(der::Input issuer_policy, der::Input subject_policy) { + assert(issuer_policy != der::Input(kAnyPolicyOid)); + assert(subject_policy != der::Input(kAnyPolicyOid)); + if (levels_.empty()) { + return; + } + + // The mapping only applies if |issuer_policy| exists in the current level. + auto issuer_policy_iter = levels_.back().find(issuer_policy); + if (issuer_policy_iter == levels_.back().end()) { + // If there is no match, it can instead match anyPolicy. + if (!current_level_.has_any_policy) { + return; + } + + // From RFC 5280, section 6.1.4, step b.1: + // + // If no node of depth i in the valid_policy_tree has a + // valid_policy of ID-P but there is a node of depth i with a + // valid_policy of anyPolicy, then generate a child node of + // the node of depth i-1 that has a valid_policy of anyPolicy + // as follows: [...] + // + // The anyPolicy node of depth i-1 is referring to the parent of the + // anyPolicy node of depth i. The parent of anyPolicy is always anyPolicy. + issuer_policy_iter = AddNodeReturningIterator(issuer_policy, {}); + } + + // Unmapped nodes have a singleton "expected_policy_set" containing their + // valid_policy. Track whether nodes have been mapped so this can be filled + // in at StartLevel(). + issuer_policy_iter->second.mapped = true; + + // Add |subject_policy| to |issuer_policy|'s "expected_policy_set". + current_level_.expected_policy_map[subject_policy].push_back(issuer_policy); + } + + // Removes the node with the specified policy from the current level. + void DeleteNode(der::Input policy) { + if (!levels_.empty()) { + levels_.back().erase(policy); + } } private: - // Deletes all nodes in the valid policy tree. - void Clear() { current_level_.clear(); } - - // Adds a node to the current level for OID |policy_oid|. The current level - // is assumed to be the root level. - void AddRootNode(const der::Input& policy_oid) { - Node new_node; - new_node.root_policy = policy_oid; - new_node.valid_policy = policy_oid; - new_node.expected_policy_set = {policy_oid}; - current_level_.push_back(std::move(new_node)); + Level::iterator AddNodeReturningIterator( + der::Input policy, + std::vector<der::Input> parent_policies) { + assert(policy != der::Input(kAnyPolicyOid)); + auto [iter, inserted] = levels_.back().insert( + std::pair{policy, Node{std::move(parent_policies)}}); + assert(inserted); + return iter; } - Level current_level_; + // The list of levels, starting from the root. + std::vector<Level> levels_; + // Additional information about the current level. + LevelDetails current_level_; }; // Class that encapsulates the state variables used by certificate path @@ -623,7 +692,7 @@ bssl::UniquePtr<EVP_PKEY> ParseAndCheckPublicKey(const der::Input& spki, CertErrors* errors); - ValidPolicyTree valid_policy_tree_; + ValidPolicyGraph valid_policy_graph_; // Will contain a NameConstraints for each previous cert in the chain which // had nameConstraints. This corresponds to the permitted_subtrees and @@ -719,12 +788,9 @@ // certificate and the valid_policy_tree is not NULL, process // the policy information by performing the following steps in // order: - if (cert.has_policy_oids() && !valid_policy_tree_.IsNull()) { - ValidPolicyTree::Level previous_level = valid_policy_tree_.StartLevel(); - - // Identify if there was a node with valid_policy == anyPolicy at depth i-1. - const ValidPolicyTree::Node* any_policy_node_prev_level = - ValidPolicyTree::FindAnyPolicyNode(previous_level); + if (cert.has_policy_oids() && !valid_policy_graph_.IsNull()) { + ValidPolicyGraph::LevelDetails previous_level = + valid_policy_graph_.StartLevel(); // (1) For each policy P not equal to anyPolicy in the // certificate policies extension, let P-OID denote the OID @@ -742,22 +808,20 @@ // child node as follows: set the valid_policy to P-OID, // set the qualifier_set to P-Q, and set the // expected_policy_set to {P-OID}. - bool found_match = false; - for (const ValidPolicyTree::Node& prev_node : previous_level) { - if (SetContains(prev_node.expected_policy_set, p_oid)) { - valid_policy_tree_.AddNode(prev_node, p_oid); - found_match = true; - } + auto iter = previous_level.expected_policy_map.find(p_oid); + if (iter != previous_level.expected_policy_map.end()) { + valid_policy_graph_.AddNode( + p_oid, /*parent_policies=*/std::move(iter->second)); + previous_level.expected_policy_map.erase(iter); + } else if (previous_level.has_any_policy) { + // (ii) If there was no match in step (i) and the + // valid_policy_tree includes a node of depth i-1 with + // the valid_policy anyPolicy, generate a child node with + // the following values: set the valid_policy to P-OID, + // set the qualifier_set to P-Q, and set the + // expected_policy_set to {P-OID}. + valid_policy_graph_.AddNodeWithParentAnyPolicy(p_oid); } - - // (ii) If there was no match in step (i) and the - // valid_policy_tree includes a node of depth i-1 with - // the valid_policy anyPolicy, generate a child node with - // the following values: set the valid_policy to P-OID, - // set the qualifier_set to P-Q, and set the - // expected_policy_set to {P-OID}. - if (!found_match && any_policy_node_prev_level) - valid_policy_tree_.AddNode(*any_policy_node_prev_level, p_oid); } // (2) If the certificate policies extension includes the policy @@ -775,20 +839,12 @@ // this node. if (cert_has_any_policy && ((inhibit_any_policy_ > 0) || (!is_target_cert && IsSelfIssued(cert)))) { - // Keep track of the existing policies at depth i. - std::set<der::Input> child_node_policies; - for (const ValidPolicyTree::Node& node : - valid_policy_tree_.current_level()) - child_node_policies.insert(node.valid_policy); - - for (const ValidPolicyTree::Node& prev_node : previous_level) { - for (const der::Input& expected_policy : - prev_node.expected_policy_set) { - if (!SetContains(child_node_policies, expected_policy)) { - child_node_policies.insert(expected_policy); - valid_policy_tree_.AddNode(prev_node, expected_policy); - } - } + for (auto& [p_oid, parent_policies] : + previous_level.expected_policy_map) { + valid_policy_graph_.AddNode(p_oid, std::move(parent_policies)); + } + if (previous_level.has_any_policy) { + valid_policy_graph_.AddAnyPolicyNode(); } } @@ -797,19 +853,18 @@ // this step until there are no nodes of depth i-1 or less // without children. // - // Nothing needs to be done for this step, since this implementation only - // stores the nodes at depth i, and the entire level has already been - // calculated. + // This implementation does this as part of GetValidRootPolicySet(). Only + // the current level needs to be pruned to compute the policy graph. } // (e) If the certificate policies extension is not present, set the // valid_policy_tree to NULL. if (!cert.has_policy_oids()) - valid_policy_tree_.SetNull(); + valid_policy_graph_.SetNull(); // (f) Verify that either explicit_policy is greater than 0 or the // valid_policy_tree is not equal to NULL; - if (!((explicit_policy_ > 0) || !valid_policy_tree_.IsNull())) + if (!((explicit_policy_ > 0) || !valid_policy_graph_.IsNull())) errors->AddError(cert_errors::kNoValidPolicy); } @@ -827,10 +882,11 @@ if (mapping.issuer_domain_policy == der::Input(kAnyPolicyOid) || mapping.subject_domain_policy == der::Input(kAnyPolicyOid)) { // Because this implementation continues processing certificates after - // this error, clear the valid policy tree to ensure the + // this error, clear the valid policy graph to ensure the // "user_constrained_policy_set" output upon failure is empty. - valid_policy_tree_.SetNull(); + valid_policy_graph_.SetNull(); errors->AddError(cert_errors::kPolicyMappingAnyPolicy); + return; } } @@ -860,32 +916,9 @@ // equivalent to ID-P by the policy mappings extension. // if (policy_mapping_ > 0) { - const ValidPolicyTree::Node* any_policy_node = - ValidPolicyTree::FindAnyPolicyNode(valid_policy_tree_.current_level()); - - // Group mappings by issuer domain policy. - std::map<der::Input, std::set<der::Input>> mappings; for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) { - mappings[mapping.issuer_domain_policy].insert( - mapping.subject_domain_policy); - } - - for (const auto& it : mappings) { - const der::Input& issuer_domain_policy = it.first; - const std::set<der::Input>& subject_domain_policies = it.second; - bool found_node = false; - - for (ValidPolicyTree::Node& node : valid_policy_tree_.current_level()) { - if (node.valid_policy == issuer_domain_policy) { - node.expected_policy_set = subject_domain_policies; - found_node = true; - } - } - - if (!found_node && any_policy_node) { - valid_policy_tree_.AddNodeWithExpectedPolicySet( - *any_policy_node, issuer_domain_policy, subject_domain_policies); - } + valid_policy_graph_.AddPolicyMapping(mapping.issuer_domain_policy, + mapping.subject_domain_policy); } } @@ -905,8 +938,7 @@ // depth i-1 or less without children. if (policy_mapping_ == 0) { for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) { - ValidPolicyTree::DeleteNodesMatchingValidPolicy( - mapping.issuer_domain_policy, &valid_policy_tree_.current_level()); + valid_policy_graph_.DeleteNode(mapping.issuer_domain_policy); } } } @@ -1181,7 +1213,7 @@ // If either (1) the value of explicit_policy variable is greater than // zero or (2) the valid_policy_tree is not NULL, then path processing // has succeeded. - if (!(explicit_policy_ > 0 || !valid_policy_tree_.IsNull())) { + if (!(explicit_policy_ > 0 || !valid_policy_graph_.IsNull())) { errors->AddError(cert_errors::kNoValidPolicy); } @@ -1348,7 +1380,7 @@ // if n is used in place of n+1). const size_t n = certs.size() - 1; - valid_policy_tree_.Init(user_initial_policy_set); + valid_policy_graph_.Init(user_initial_policy_set); // RFC 5280 section section 6.1.2: // @@ -1443,9 +1475,9 @@ } if (user_constrained_policy_set) { - // valid_policy_tree_ already contains the intersection of valid policies + // valid_policy_graph_ already contains the intersection of valid policies // with user_initial_policy_set. - valid_policy_tree_.GetValidRootPolicySet(user_constrained_policy_set); + valid_policy_graph_.GetValidRootPolicySet(user_constrained_policy_set); } // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
diff --git a/net/data/url_request_unittest/expect-ct-header-multiple.html b/net/data/url_request_unittest/expect-ct-header-multiple.html deleted file mode 100644 index e69de29..0000000 --- a/net/data/url_request_unittest/expect-ct-header-multiple.html +++ /dev/null
diff --git a/net/data/url_request_unittest/expect-ct-header-preload.html b/net/data/url_request_unittest/expect-ct-header-preload.html deleted file mode 100644 index e69de29..0000000 --- a/net/data/url_request_unittest/expect-ct-header-preload.html +++ /dev/null
diff --git a/net/data/url_request_unittest/expect-ct-header.html b/net/data/url_request_unittest/expect-ct-header.html deleted file mode 100644 index e69de29..0000000 --- a/net/data/url_request_unittest/expect-ct-header.html +++ /dev/null
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index a0b4646..7a03d252 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -300,7 +300,7 @@ } if (is_linux || is_chromeos) { - # TODO(crbug.com/1302059): After PPAPI deprecation, there will only be one + # TODO(crbug.com/702990): After PPAPI deprecation, there will only be one # caller left. Move inside the file with the caller. static_library("font_table_linux") { sources = [ "font_table_linux.cc" ]
diff --git a/pdf/paint_manager.cc b/pdf/paint_manager.cc index d17c80f9..667b9f9 100644 --- a/pdf/paint_manager.cc +++ b/pdf/paint_manager.cc
@@ -305,7 +305,7 @@ SkSamplingOptions(), /*paint=*/nullptr); client_->UpdateSnapshot(std::move(snapshot)); - // TODO(crbug.com/1302059): Complete flush synchronously. + // TODO(crbug.com/1403311): Complete flush synchronously. base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(&PaintManager::OnFlushComplete, weak_factory_.GetWeakPtr()));
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index aa185962..f6ea2bb4 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -455,9 +455,6 @@ if (!total_translate_.IsZero()) canvas->translate(total_translate_.x(), total_translate_.y()); - if (device_to_css_scale_ != 1.0f) - canvas->scale(device_to_css_scale_, device_to_css_scale_); - // Position layer at plugin origin before layer scaling. if (!plugin_rect_.origin().IsOrigin()) canvas->translate(plugin_rect_.x(), plugin_rect_.y()); @@ -544,18 +541,8 @@ blink::WebInputEventResult PdfViewWebPlugin::HandleInputEvent( const blink::WebCoalescedInputEvent& event, ui::Cursor* cursor) { - // TODO(crbug.com/1302059): The input events received by the Pepper plugin - // already have the viewport-to-DIP scale applied. The scaling done here - // should be moved into `HandleWebInputEvent()` once the Pepper plugin is - // removed. - std::unique_ptr<blink::WebInputEvent> scaled_event = - ui::ScaleWebInputEvent(event.Event(), viewport_to_dip_scale_); - - const blink::WebInputEvent& event_to_handle = - scaled_event ? *scaled_event : event.Event(); - const blink::WebInputEventResult result = - HandleWebInputEvent(event_to_handle) + HandleWebInputEvent(event.Event()) ? blink::WebInputEventResult::kHandledApplication : blink::WebInputEventResult::kNotHandled; @@ -924,8 +911,7 @@ } void PdfViewWebPlugin::CaretChanged(const gfx::Rect& caret_rect) { - caret_rect_ = gfx::ScaleToEnclosingRect( - caret_rect + available_area_.OffsetFromOrigin(), device_to_css_scale_); + caret_rect_ = caret_rect + available_area_.OffsetFromOrigin(); } void PdfViewWebPlugin::GetDocumentPassword( @@ -1659,9 +1645,7 @@ message.Set("token", token); client_->PostMessage(std::move(message)); - // TODO(crbug.com/1302059): Is there a good reason to null-terminate here? - pdf_service_->SaveUrlAs(GURL(url_.c_str()), - network::mojom::ReferrerPolicy::kDefault); + pdf_service_->SaveUrlAs(GURL(url_), network::mojom::ReferrerPolicy::kDefault); } void PdfViewWebPlugin::InvalidatePluginContainer() { @@ -1888,7 +1872,6 @@ } viewport_to_dip_scale_ = scale; - device_to_css_scale_ = 1.0f; UpdateScaledValues(); } @@ -2002,10 +1985,12 @@ return false; // `engine_` expects input events in device coordinates. + float viewport_to_device_scale = viewport_to_dip_scale_ * device_scale_; std::unique_ptr<blink::WebInputEvent> transformed_event = ui::TranslateAndScaleWebInputEvent( - event, gfx::Vector2dF(-available_area_.x() / device_scale_, 0), - device_scale_); + event, + gfx::Vector2dF(-available_area_.x() / viewport_to_device_scale, 0), + viewport_to_device_scale); const blink::WebInputEvent& event_to_handle = transformed_event ? *transformed_event : event;
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h index 6b50cc5ee..025fe199 100644 --- a/pdf/pdf_view_web_plugin.h +++ b/pdf/pdf_view_web_plugin.h
@@ -655,9 +655,6 @@ // The viewport coordinates to DIP (device-independent pixel) ratio. float viewport_to_dip_scale_ = 1.0f; - // The device pixel to CSS pixel ratio. - float device_to_css_scale_ = 1.0f; - // Combined translate from snapshot to device to CSS pixels. gfx::Vector2dF total_translate_;
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/services/viz/public/cpp/gpu/context_provider_command_buffer.h index e434c1b..04de90c5 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.h +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
@@ -84,8 +84,7 @@ command_buffer_metrics::ContextType type, base::SharedMemoryMapper* buffer_mapper = nullptr); - // Virtual for testing. - virtual gpu::CommandBufferProxyImpl* GetCommandBufferProxy(); + gpu::CommandBufferProxyImpl* GetCommandBufferProxy(); // Gives the GL internal format that should be used for calling CopyTexImage2D // on the default framebuffer. uint32_t GetCopyTextureInternalFormat();
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index f6be297..c27c7cd3 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -509,6 +509,12 @@ virtual void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) {} + // Called when an image ad rectangle changed. An empty `image_ad_rect` is used + // to signal the removal of the rectangle. Only invoked on the main frame. + virtual void OnMainFrameImageAdRectangleChanged( + int element_id, + const gfx::Rect& image_ad_rect) {} + // Called when an overlay interstitial pop up ad is detected. virtual void OnOverlayPopupAdDetected() {}
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl index ab72616..6819ca3 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -38,11 +38,7 @@ {% endmacro %} {% macro style_access(property) %} - {%- if property.writable %} -state.Style()-> - {%- else %} state.StyleBuilder(). - {%- endif %} {% endmacro %} {% macro set_value(property) %}
diff --git a/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py b/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py index b568d2af..8d941c64 100644 --- a/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py +++ b/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py
@@ -136,15 +136,14 @@ default_value: Default value for this field when it is first initialized """ - def __init__(self, field_role, name_for_methods, writable, property_name, - type_name, wrapper_pointer_name, field_template, size, - default_value, derived_from, custom_copy, custom_compare, - mutable, getter_method_name, setter_method_name, - initial_method_name, computed_style_custom_functions, + def __init__(self, field_role, name_for_methods, property_name, type_name, + wrapper_pointer_name, field_template, size, default_value, + derived_from, custom_copy, custom_compare, mutable, + getter_method_name, setter_method_name, initial_method_name, + computed_style_custom_functions, computed_style_protected_functions, **kwargs): name_source = NameStyleConverter(name_for_methods) self.name = name_source.to_class_data_member() - self.writable = writable self.property_name = property_name self.type_name = type_name self.wrapper_pointer_name = wrapper_pointer_name
diff --git a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py index bd791e1..fb9f6ae 100755 --- a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py +++ b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
@@ -170,10 +170,9 @@ def _mark_builder_flags(group): - """Mark all fields as builder fields, and set writable.""" + """Mark all fields as builder fields.""" for field in group.fields: field.builder = True - field.writable = True for subgroup in group.subgroups: _mark_builder_flags(subgroup) @@ -321,7 +320,6 @@ 'property', name_for_methods, property_name=property_.name.original, - writable=property_.writable, inherited=property_.inherited, independent=property_.independent, semi_independent_variable=property_.semi_independent_variable, @@ -357,7 +355,6 @@ 'inherited_flag', name_for_methods, property_name=property_.name.original, - writable=False, type_name='bool', wrapper_pointer_name=None, field_template='primitive',
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/base.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/base.tmpl index 9ae3448..c272a5d 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/base.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/base.tmpl
@@ -9,7 +9,7 @@ {%- endmacro %} {% macro decl_setter_method(field, visibility) -%} -{% if field.setter_visibility == visibility and field.writable %} +{% if field.setter_visibility == visibility and field.builder %} void {{setter_method_name(field)}}({{const_ref(field)}} v) { {{set_if_changed(field, encode(field, "v"))|indent(2)}} } @@ -17,7 +17,7 @@ {%- endmacro %} {% macro decl_move_method(field, visibility) -%} -{% if field.setter_visibility == visibility and field.writable %} +{% if field.setter_visibility == visibility and field.builder %} void {{setter_method_name(field)}}({{rvalue_ref(field)}} v) { {{move_if_changed(field, encode(field, "v"))|indent(2)}} } @@ -25,7 +25,7 @@ {%- endmacro %} {% macro decl_resetter_method(field, visibility) -%} -{% if field.resetter_visibility == visibility and field.writable %} +{% if field.resetter_visibility == visibility and field.builder %} inline void {{resetter_method_name(field)}}() { {{setter_expression(field)}} = {{encode(field, field.default_value)}}; } @@ -37,7 +37,7 @@ Internal suffix. #} {% macro decl_mutable_method(field) -%} -{% if field.writable %} +{% if field.builder %} {{nonconst_ref(field)}} {{mutable_method_name(field)}}() { return {{decode(field, setter_expression(field))}}; }
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/monotonic_flag.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/monotonic_flag.tmpl index 768dbd35..0ec4651 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/monotonic_flag.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/monotonic_flag.tmpl
@@ -4,7 +4,7 @@ {% macro decl_public_methods(field) %} {{base.decl_public_getter_method(field)}} -{% if field.writable or field.mutable %} +{% if field.builder or field.mutable %} void {{field.setter_method_name}}() {{print_if(field.mutable, "const ")}}{ {{set_if_changed(field, encode(field, "true"))|indent(2)}} }
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/pointer.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/pointer.tmpl index b9083be593..0f7bf297 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/pointer.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/pointer.tmpl
@@ -6,7 +6,7 @@ return {{decode(field, getter_expression(field))}}.get(); } -{% if field.writable %} +{% if field.builder %} void {{field.setter_method_name}}({{field.wrapper_pointer_name}}<{{field.type_name}}> v) { {% if field.group.parent %} {{setter_expression(field)}} = std::move(v);
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index aac58b6..9128c5f 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -71,16 +71,6 @@ ], }, - // Properties which are writable have setters on ComputedStyle. - // All other properties must use the ComputedStyleBuilder for setting - // the values of properties. - // - // TODO(crbug.com/1377295): Eventually nothing should be writable. - writable: { - default: false, - valid_type: "bool", - }, - // Affects how the style building functions are generated. // // Several property groups (e.g. color properties) deviate from the default
diff --git a/third_party/blink/renderer/core/frame/frame_client.h b/third_party/blink/renderer/core/frame/frame_client.h index beb8795d..ec6ca356 100644 --- a/third_party/blink/renderer/core/frame/frame_client.h +++ b/third_party/blink/renderer/core/frame/frame_client.h
@@ -7,6 +7,7 @@ #include "base/unguessable_token.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" namespace gfx { @@ -44,6 +45,12 @@ virtual void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) {} + // Called when an image ad rectangle changed. An empty `image_ad_rect` is used + // to signal the removal of the rectangle. Only invoked on the main frame. + virtual void OnMainFrameImageAdRectangleChanged( + DOMNodeId element_id, + const gfx::Rect& image_ad_rect) {} + virtual ~FrameClient() = default; virtual void Trace(Visitor* visitor) const {}
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc index 50f14f38..dccf5ca 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -1070,6 +1070,14 @@ main_frame_viewport_rect); } +void LocalFrameClientImpl::OnMainFrameImageAdRectangleChanged( + DOMNodeId element_id, + const gfx::Rect& image_ad_rect) { + DCHECK(web_frame_->Client()); + web_frame_->Client()->OnMainFrameImageAdRectangleChanged(element_id, + image_ad_rect); +} + void LocalFrameClientImpl::OnOverlayPopupAdDetected() { DCHECK(web_frame_->Client()); web_frame_->Client()->OnOverlayPopupAdDetected();
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h index befd55a8b9..9592a957 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -254,6 +254,10 @@ void OnMainFrameViewportRectangleChanged( const gfx::Rect& main_frame_viewport_rect) override; + void OnMainFrameImageAdRectangleChanged( + DOMNodeId element_id, + const gfx::Rect& image_ad_rect) override; + void OnOverlayPopupAdDetected() override; void OnLargeStickyAdDetected() override;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index d0b84cae..75c6ba11 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -3067,6 +3067,8 @@ SCOPED_UMA_AND_UKM_TIMER(GetUkmAggregator(), LocalFrameUkmAggregator::kCompositingCommit); + DEVTOOLS_TIMELINE_TRACE_EVENT("Layerize", inspector_layerize_event::Data, + frame_.Get()); // Skip updating property trees, pushing cc::Layers, and issuing raster // invalidations if possible.
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index 92cddb8..c9d34fb2 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/core/frame/attribution_src_loader.h" #include "third_party/blink/renderer/core/frame/deprecation/deprecation.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" #include "third_party/blink/renderer/core/html/cross_origin_attribute.h" #include "third_party/blink/renderer/core/html/forms/form_associated.h" @@ -516,6 +517,13 @@ } void HTMLImageElement::RemovedFrom(ContainerNode& insertion_point) { + if (InActiveDocument() && !last_reported_ad_rect_.IsEmpty()) { + gfx::Rect empty_rect; + GetDocument().GetFrame()->Client()->OnMainFrameImageAdRectangleChanged( + DOMNodeIds::IdForNode(this), empty_rect); + last_reported_ad_rect_ = empty_rect; + } + if (!form_ || NodeTraversal::HighestAncestorOrSelf(*form_.Get()) != NodeTraversal::HighestAncestorOrSelf(*this)) ResetFormOwner(); @@ -662,6 +670,48 @@ return html_names::kSrcAttr; } +void HTMLImageElement::SetIsAdRelated() { + if (!is_ad_related_ && GetDocument().View()) { + GetDocument().View()->RegisterForLifecycleNotifications(this); + } + + is_ad_related_ = true; +} + +void HTMLImageElement::DidFinishLifecycleUpdate( + const LocalFrameView& local_frame_view) { + DCHECK(is_ad_related_); + + // Scope to the outermost frame to avoid counting image ads that are (likely) + // already in ad iframes. + LocalFrame* frame = GetDocument().GetFrame(); + if (!frame || !frame->View() || !frame->IsOutermostMainFrame()) { + return; + } + + gfx::Rect rect_to_report; + if (LayoutObject* r = GetLayoutObject()) { + gfx::Rect rect_in_viewport = r->AbsoluteBoundingBoxRect(); + + // Exclude image ads that are invisible or too small (e.g. tracking pixels). + if (rect_in_viewport.width() > 1 && rect_in_viewport.height() > 1) { + if (!image_ad_use_counter_recorded_) { + UseCounter::Count(GetDocument(), WebFeature::kImageAd); + image_ad_use_counter_recorded_ = true; + } + + rect_to_report = + rect_in_viewport + frame->View()->LayoutViewport()->ScrollOffsetInt(); + } + } + + if (last_reported_ad_rect_ != rect_to_report) { + frame->Client()->OnMainFrameImageAdRectangleChanged( + DOMNodeIds::IdForNode(this), rect_to_report); + last_reported_ad_rect_ = rect_to_report; + } +} + bool HTMLImageElement::draggable() const { // Image elements are draggable by default. return !EqualIgnoringASCIICase(FastGetAttribute(html_names::kDraggableAttr),
diff --git a/third_party/blink/renderer/core/html/html_image_element.h b/third_party/blink/renderer/core/html/html_image_element.h index 2c04b64..26f7485 100644 --- a/third_party/blink/renderer/core/html/html_image_element.h +++ b/third_party/blink/renderer/core/html/html_image_element.h
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/create_element_flags.h" +#include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/html/canvas/image_element_base.h" #include "third_party/blink/renderer/core/html/forms/form_associated.h" #include "third_party/blink/renderer/core/html/html_element.h" @@ -52,7 +53,8 @@ : public HTMLElement, public ImageElementBase, public ActiveScriptWrappable<HTMLImageElement>, - public FormAssociated { + public FormAssociated, + public LocalFrameView::LifecycleNotificationObserver { DEFINE_WRAPPERTYPEINFO(); public: @@ -185,7 +187,7 @@ } // Keeps track of whether the image comes from an ad. - void SetIsAdRelated() { is_ad_related_ = true; } + void SetIsAdRelated(); bool IsAdRelated() const override { return is_ad_related_; } // Keeps track whether this image is an LCP element. @@ -269,6 +271,9 @@ void NotifyViewportChanged(); void CreateMediaQueryListIfDoesNotExist(); + // LocalFrameView::LifecycleNotificationObserver + void DidFinishLifecycleUpdate(const LocalFrameView&) override; + Member<HTMLImageLoader> image_loader_; Member<ViewportChangeListener> listener_; Member<HTMLFormElement> form_; @@ -294,6 +299,14 @@ std::unique_ptr<LazyLoadImageObserver::VisibleLoadTimeMetrics> visible_load_time_metrics_; + + bool image_ad_use_counter_recorded_ = false; + + // The last rectangle reported to the the `PageTimingMetricsSender`. + // `last_reported_ad_rect_` is empty if there's no report before, or if the + // last report was used to signal the removal of this element (i.e. both cases + // will be handled the same way). + gfx::Rect last_reported_ad_rect_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_image_element_test.cc b/third_party/blink/renderer/core/html/html_image_element_test.cc index b2cc608..d70557fe 100644 --- a/third_party/blink/renderer/core/html/html_image_element_test.cc +++ b/third_party/blink/renderer/core/html/html_image_element_test.cc
@@ -9,21 +9,54 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/parser/css_parser.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/security_context.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" namespace blink { -class HTMLImageElementTest : public PageTestBase { +namespace { + +class TestFrameClient : public EmptyLocalFrameClient { + public: + void OnMainFrameImageAdRectangleChanged( + DOMNodeId element_id, + const gfx::Rect& image_ad_rect) override { + observed_image_ad_rects_.emplace_back(element_id, image_ad_rect); + } + + const std::vector<std::pair<DOMNodeId, gfx::Rect>>& observed_image_ad_rects() + const { + return observed_image_ad_rects_; + } + + private: + std::vector<std::pair<DOMNodeId, gfx::Rect>> observed_image_ad_rects_; +}; + +} // namespace + +class HTMLImageElementTest : public PageTestBase, + private ScopedLayoutNGForTest { protected: static constexpr int kViewportWidth = 500; static constexpr int kViewportHeight = 600; + HTMLImageElementTest() : ScopedLayoutNGForTest(false) {} + void SetUp() override { - PageTestBase::SetUp(gfx::Size(kViewportWidth, kViewportHeight)); + test_frame_client_ = MakeGarbageCollected<TestFrameClient>(); + + PageTestBase::SetupPageWithClients( + nullptr, test_frame_client_.Get(), nullptr, + gfx::Size(kViewportWidth, kViewportHeight)); } + + Persistent<TestFrameClient> test_frame_client_; }; // Instantiate class constants. Not needed after C++17. @@ -107,4 +140,94 @@ } } +TEST_F(HTMLImageElementTest, ImageAdRectangleUpdate) { + GetDocument().GetSettings()->SetScriptEnabled(true); + + SetBodyInnerHTML(R"HTML( + <img id="target" + style="position:absolute;top:5px;left:5px;width:10px;height:10px;"> + </img> + + <p style="position:absolute;top:10000px;">abc</p> + )HTML"); + + HTMLImageElement* image = To<HTMLImageElement>(GetElementById("target")); + image->SetIsAdRelated(); + + EXPECT_TRUE(test_frame_client_->observed_image_ad_rects().empty()); + + UpdateAllLifecyclePhasesForTest(); + + EXPECT_EQ(test_frame_client_->observed_image_ad_rects().size(), 1u); + DOMNodeId id = test_frame_client_->observed_image_ad_rects()[0].first; + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[0].second, + gfx::Rect(5, 5, 10, 10)); + + // Scrolling won't trigger another notification, as the rectangle hasn't + // changed relative to the page. + { + auto* script = GetDocument().CreateRawElement(html_names::kScriptTag); + script->setTextContent(R"JS( + window.scroll(0, 100); + )JS"); + GetDocument().body()->appendChild(script); + UpdateAllLifecyclePhasesForTest(); + } + + EXPECT_EQ(test_frame_client_->observed_image_ad_rects().size(), 1u); + + // Update the size to 1x1. A new notification is expected to signal the + // removal of the element. + { + auto* script = GetDocument().CreateRawElement(html_names::kScriptTag); + script->setTextContent(R"JS( + var image = document.getElementById('target'); + image.style.width = '1px'; + image.style.height = '1px'; + )JS"); + GetDocument().body()->appendChild(script); + UpdateAllLifecyclePhasesForTest(); + } + + EXPECT_EQ(test_frame_client_->observed_image_ad_rects().size(), 2u); + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[1].first, id); + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[1].second, + gfx::Rect()); + + // Update the size to 30x30. A new notification is expected to signal the new + // rectangle. + { + auto* script = GetDocument().CreateRawElement(html_names::kScriptTag); + script->setTextContent(R"JS( + var image = document.getElementById('target'); + image.style.width = '30px'; + image.style.height = '30px'; + )JS"); + GetDocument().body()->appendChild(script); + UpdateAllLifecyclePhasesForTest(); + } + + EXPECT_EQ(test_frame_client_->observed_image_ad_rects().size(), 3u); + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[2].first, id); + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[2].second, + gfx::Rect(5, 5, 30, 30)); + + // Remove the element. A new notification is expected to signal the removal of + // the element. + { + auto* script = GetDocument().CreateRawElement(html_names::kScriptTag); + script->setTextContent(R"JS( + var image = document.getElementById('target'); + image.remove() + )JS"); + GetDocument().body()->appendChild(script); + UpdateAllLifecyclePhasesForTest(); + } + + EXPECT_EQ(test_frame_client_->observed_image_ad_rects().size(), 4u); + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[3].first, id); + EXPECT_EQ(test_frame_client_->observed_image_ad_rects()[3].second, + gfx::Rect()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc index 83aa91c..fca8e6b 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -1162,6 +1162,13 @@ FillCommonFrameData(dict, frame); } +void inspector_layerize_event::Data(perfetto::TracedValue context, + LocalFrame* frame) { + auto dict = std::move(context).WriteDictionary(); + FrameEventData(dict, frame); + dict.Add("frame", IdentifiersFactory::FrameId(frame)); +} + void inspector_mark_load_event::Data(perfetto::TracedValue context, LocalFrame* frame) { auto dict = std::move(context).WriteDictionary();
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.h b/third_party/blink/renderer/core/inspector/inspector_trace_events.h index be5b59d..09bad868 100644 --- a/third_party/blink/renderer/core/inspector/inspector_trace_events.h +++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
@@ -462,6 +462,10 @@ void Data(perfetto::TracedValue context, LocalFrame*); } +namespace inspector_layerize_event { +void Data(perfetto::TracedValue context, LocalFrame*); +} + namespace inspector_mark_load_event { void Data(perfetto::TracedValue context, LocalFrame*); }
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc index 1f7791a..12b53da 100644 --- a/third_party/blink/renderer/core/layout/layout_image.cc +++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -463,17 +463,6 @@ media_element_parser_helpers::CheckUnsizedMediaViolation( this, image_element->IsDefaultIntrinsicSize()); image_element->SetAutoSizesUsecounter(); - - // Scope to the outermost frame to avoid counting image ads that are - // (likely) already in ad iframes. Exclude image ads that are invisible or - // too small (e.g. tracking pixels). - if (!image_ad_use_counter_recorded_ && image_element->IsAdRelated() && - GetDocument().IsInOutermostMainFrame() && - image_element->LayoutBoxWidth() > 1 && - image_element->LayoutBoxHeight() > 1) { - UseCounter::Count(GetDocument(), WebFeature::kImageAd); - image_ad_use_counter_recorded_ = true; - } } else if (auto* video_element = DynamicTo<HTMLVideoElement>(node)) { media_element_parser_helpers::CheckUnsizedMediaViolation( this, video_element->IsDefaultIntrinsicSize());
diff --git a/third_party/blink/renderer/core/layout/layout_image.h b/third_party/blink/renderer/core/layout/layout_image.h index 517f9fb7..be4e212 100644 --- a/third_party/blink/renderer/core/layout/layout_image.h +++ b/third_party/blink/renderer/core/layout/layout_image.h
@@ -179,8 +179,6 @@ // This field stores whether this image is generated with 'content'. bool is_generated_content_ = false; - - bool image_ad_use_counter_recorded_ = false; }; template <>
diff --git a/third_party/blink/renderer/core/testing/page_test_base.cc b/third_party/blink/renderer/core/testing/page_test_base.cc index 3722a3a..315fad14 100644 --- a/third_party/blink/renderer/core/testing/page_test_base.cc +++ b/third_party/blink/renderer/core/testing/page_test_base.cc
@@ -147,7 +147,8 @@ void PageTestBase::SetupPageWithClients( ChromeClient* chrome_client, LocalFrameClient* local_frame_client, - FrameSettingOverrideFunction setting_overrider) { + FrameSettingOverrideFunction setting_overrider, + gfx::Size size) { DCHECK(!dummy_page_holder_) << "Page should be set up only once"; auto setter = base::BindLambdaForTesting([&](Settings& settings) { if (setting_overrider) @@ -155,9 +156,9 @@ if (enable_compositing_) settings.SetAcceleratedCompositingEnabled(true); }); - dummy_page_holder_ = std::make_unique<DummyPageHolder>( - gfx::Size(800, 600), chrome_client, local_frame_client, std::move(setter), - GetTickClock()); + dummy_page_holder_ = + std::make_unique<DummyPageHolder>(size, chrome_client, local_frame_client, + std::move(setter), GetTickClock()); // Use no-quirks (ake "strict") mode by default. GetDocument().SetCompatibilityMode(Document::kNoQuirksMode);
diff --git a/third_party/blink/renderer/core/testing/page_test_base.h b/third_party/blink/renderer/core/testing/page_test_base.h index 52b8d4e1..48a515e 100644 --- a/third_party/blink/renderer/core/testing/page_test_base.h +++ b/third_party/blink/renderer/core/testing/page_test_base.h
@@ -67,7 +67,8 @@ void SetUp(gfx::Size); void SetupPageWithClients(ChromeClient* = nullptr, LocalFrameClient* = nullptr, - FrameSettingOverrideFunction = nullptr); + FrameSettingOverrideFunction = nullptr, + gfx::Size size = gfx::Size(800, 600)); // TODO(shanmuga.m@samsung.com): These two function to be unified. void SetBodyContent(const std::string&); void SetBodyInnerHTML(const String&);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index 3e18eef..9e85b9f2 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -128,8 +128,9 @@ } ScrollableArea* AXLayoutObject::GetScrollableAreaIfScrollable() const { - if (IsWebArea()) + if (IsA<Document>(GetNode())) { return DocumentFrameView()->LayoutViewport(); + } if (auto* box = DynamicTo<LayoutBox>(GetLayoutObject())) { PaintLayerScrollableArea* scrollable_area = box->GetScrollableArea(); @@ -224,8 +225,10 @@ if (IsA<HTMLCanvasElement>(node)) return ax::mojom::blink::Role::kCanvas; - if (IsA<LayoutView>(*layout_object_)) - return ax::mojom::blink::Role::kRootWebArea; + if (IsA<LayoutView>(*layout_object_)) { + return ParentObject() ? ax::mojom::blink::Role::kGroup + : ax::mojom::blink::Role::kRootWebArea; + } if (node && node->IsSVGElement()) { if (layout_object_->IsSVGImage()) @@ -429,8 +432,9 @@ // node of the main web area, so force that node to always be unignored. // The web area for a <select>'s' popup document is ignored, because the // popup object hierarchy is constructed without the document root. - if (IsWebArea()) + if (IsA<Document>(GetNode())) { return CachedParentObject() && CachedParentObject()->IsMenuList(); + } const Node* node = GetNode(); if (IsA<HTMLHtmlElement>(node)) @@ -1151,8 +1155,9 @@ AXObject* AXLayoutObject::AccessibilityHitTest(const gfx::Point& point) const { // Must be called for the document's root or a popup's root. - if (RoleValue() != ax::mojom::blink::Role::kRootWebArea || !layout_object_) + if (!IsA<Document>(GetNode()) || !layout_object_) { return nullptr; + } // Must be called with lifecycle >= pre-paint clean DCHECK_GE(GetDocument()->Lifecycle().GetState(),
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 6039892..bf596cd 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -756,8 +756,9 @@ // All nodes must have an unignored parent within their tree under // the root node of the web area, so force that node to always be unignored. - if (IsWebArea()) + if (IsA<Document>(GetNode())) { return false; + } DCHECK_NE(role_, ax::mojom::blink::Role::kUnknown); // Use AXLayoutObject::ComputeAccessibilityIsIgnored(). @@ -2550,7 +2551,7 @@ if (!layout_object) return Color::kTransparent.Rgb(); - if (IsWebArea()) { + if (IsA<Document>(GetNode())) { LocalFrameView* view = DocumentFrameView(); if (view) return view->BaseBackgroundColor().Rgb(); @@ -2899,8 +2900,10 @@ if (IsLink()) // <area>, <link>, <html:a> or <svg:a> return GetElement()->HrefURL(); - if (IsWebArea() && GetDocument()) + if (IsWebArea()) { + DCHECK(GetDocument()); return GetDocument()->Url(); + } auto* html_image_element = DynamicTo<HTMLImageElement>(GetNode()); if (IsImage() && html_image_element) { @@ -2920,18 +2923,28 @@ AXObject* AXNodeObject::ChooserPopup() const { // When color & date chooser popups are visible, they can be found in the tree - // as a WebArea child of the <input> control itself. + // as a group child of the <input> control itself. switch (native_role_) { case ax::mojom::blink::Role::kColorWell: + case ax::mojom::blink::Role::kComboBoxSelect: case ax::mojom::blink::Role::kDate: - case ax::mojom::blink::Role::kDateTime: { + case ax::mojom::blink::Role::kDateTime: + case ax::mojom::blink::Role::kInputTime: + case ax::mojom::blink::Role::kTextFieldWithComboBox: { for (const auto& child : ChildrenIncludingIgnored()) { - if (child->IsWebArea()) + if (IsA<Document>(child->GetNode())) { return child; + } } return nullptr; } default: +#if DCHECK_IS_ON() + for (const auto& child : ChildrenIncludingIgnored()) { + DCHECK(!IsA<Document>(child->GetNode())) + << "Chooser popup exists for " << native_role_; + } +#endif return nullptr; } } @@ -4022,7 +4035,6 @@ auto* html_input_element = DynamicTo<HTMLInputElement>(GetNode()); if (html_input_element) { AddChildAndCheckIncluded(html_input_element->PopupRootAXObject()); - return; } } @@ -4498,7 +4510,7 @@ // If it's the root, get the computed language for the document element, // because the root LayoutObject doesn't have the right value. - if (RoleValue() == ax::mojom::blink::Role::kRootWebArea) { + if (IsWebArea()) { Element* document_element = GetDocument()->documentElement(); if (!document_element) return g_empty_atom; @@ -5315,8 +5327,7 @@ } // Document. - if (IsWebArea()) { - Document* document = GetDocument(); + if (Document* document = DynamicTo<Document>(GetNode())) { if (document) { name_from = ax::mojom::blink::NameFrom::kAttribute; if (name_sources) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 59d9dc4..bdaa23da 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -860,7 +860,7 @@ DCHECK(node->isConnected()) << "Should not call with disconnected node: " << node; - // A WebArea's parent should be the page popup owner, if any, otherwise null. + // A document's parent should be the page popup owner, if any, otherwise null. if (auto* document = DynamicTo<Document>(node)) { LocalFrame* frame = document->GetFrame(); DCHECK(frame); @@ -1500,7 +1500,7 @@ void AXObject::SerializeHTMLTagAndClass(ui::AXNodeData* node_data) { Element* element = GetElement(); if (!element) { - if (ui::IsPlatformDocument(RoleValue())) { + if (IsA<Document>(GetNode())) { TruncateAndAddStringAttribute( node_data, ax::mojom::blink::StringAttribute::kHtmlTag, "#document"); } @@ -1762,8 +1762,17 @@ } } - if (ui::IsPlatformDocument(node_data->role) && !IsLoaded()) - node_data->AddBoolAttribute(ax::mojom::blink::BoolAttribute::kBusy, true); + if (IsA<Document>(GetNode())) { + if (!IsLoaded()) { + node_data->AddBoolAttribute(ax::mojom::blink::BoolAttribute::kBusy, true); + } + if (AXObject* parent = ParentObject()) { + DCHECK(parent->ChooserPopup() == this) + << "ChooserPopup missing for: " << parent->ToString(true); + node_data->AddIntAttribute(ax::mojom::blink::IntAttribute::kPopupForId, + parent->AXObjectID()); + } + } if (node_data->role == ax::mojom::blink::Role::kColorWell) { node_data->AddIntAttribute(ax::mojom::blink::IntAttribute::kColorValue, @@ -3048,8 +3057,9 @@ bool AXObject::ComputeIsAriaHidden(IgnoredReasons* ignored_reasons) const { // The root node of a document or popup document cannot be aria-hidden. - if (IsWebArea()) + if (IsA<Document>(GetNode())) { return false; + } // aria-hidden:true works a bit like display:none. // * aria-hidden=true affects entire subtree. @@ -5792,13 +5802,14 @@ } if (clips_children) { - if (IsWebArea()) + if (IsA<Document>(GetNode())) { *clips_children = true; - else + } else { *clips_children = layout_object->HasNonVisibleOverflow(); + } } - if (IsWebArea()) { + if (IsA<Document>(GetNode())) { if (LocalFrameView* view = layout_object->GetFrame()->View()) { out_bounds_in_container.set_size(gfx::SizeF(view->Size())); @@ -5844,8 +5855,9 @@ if (layout_object->IsAbsolutePositioned()) { // If it's absolutely positioned, the container must be the // nearest positioned container, or the root. - if (container->IsWebArea()) + if (IsA<LayoutView>(layout_object)) { break; + } if (container_layout_object->IsPositioned()) break; } else {
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.cc b/third_party/blink/renderer/platform/audio/audio_destination.cc index cc607b84..2523346 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.cc +++ b/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -242,14 +242,6 @@ return web_audio_device_->FramesPerBuffer(); } -size_t AudioDestination::HardwareBufferSize() { - return Platform::Current()->AudioHardwareBufferSize(); -} - -float AudioDestination::HardwareSampleRate() { - return static_cast<float>(Platform::Current()->AudioHardwareSampleRate()); -} - uint32_t AudioDestination::MaxChannelCount() { return Platform::Current()->AudioHardwareOutputChannels(); } @@ -275,8 +267,19 @@ const WebAudioLatencyHint& latency_hint, absl::optional<float> context_sample_rate, unsigned render_quantum_frames) - : number_of_output_channels_(number_of_output_channels), + : web_audio_device_( + Platform::Current()->CreateAudioDevice(sink_descriptor, + number_of_output_channels, + latency_hint, + this)), + callback_buffer_size_( + web_audio_device_ ? web_audio_device_->FramesPerBuffer() : 0), + number_of_output_channels_(number_of_output_channels), render_quantum_frames_(render_quantum_frames), + context_sample_rate_( + context_sample_rate.has_value() + ? context_sample_rate.value() + : (web_audio_device_ ? web_audio_device_->SampleRate() : 0)), fifo_(std::make_unique<PushPullFIFO>(number_of_output_channels, kFIFOSize, render_quantum_frames)), @@ -286,16 +289,13 @@ render_bus_( AudioBus::Create(number_of_output_channels, render_quantum_frames)), callback_(callback) { + CHECK(web_audio_device_); + SendLogMessage(String::Format("%s({output_channels=%u})", __func__, number_of_output_channels)); SendLogMessage( String::Format("%s => (FIFO size=%u bytes)", __func__, fifo_->length())); - web_audio_device_ = Platform::Current()->CreateAudioDevice( - sink_descriptor, number_of_output_channels, latency_hint, this); - DCHECK(web_audio_device_); - - callback_buffer_size_ = web_audio_device_->FramesPerBuffer(); SendLogMessage(String::Format("%s => (device callback buffer size=%u frames)", __func__, callback_buffer_size_)); SendLogMessage(String::Format("%s => (device sample rate=%.0f Hz)", __func__, @@ -319,16 +319,13 @@ fifo_->Push(render_bus_.get()); } - if (!CheckBufferSize(render_quantum_frames)) { - NOTREACHED(); - } + // Check if the requested buffer size is too large. + DCHECK_LE(callback_buffer_size_ + render_quantum_frames, kFIFOSize); - double scale_factor = 1; + double scale_factor = 1.0; - if (context_sample_rate.has_value() && - context_sample_rate.value() != web_audio_device_->SampleRate()) { - scale_factor = - context_sample_rate.value() / web_audio_device_->SampleRate(); + if (context_sample_rate_ != web_audio_device_->SampleRate()) { + scale_factor = context_sample_rate_ / web_audio_device_->SampleRate(); SendLogMessage(String::Format("%s => (resampling from %0.f Hz to %0.f Hz)", __func__, context_sample_rate.value(), web_audio_device_->SampleRate())); @@ -343,14 +340,24 @@ resampler_bus_->SetChannelData(i, render_bus_->Channel(i)->MutableData()); } resampler_bus_->set_frames(render_bus_->length()); - context_sample_rate_ = context_sample_rate.value(); } else { - context_sample_rate_ = web_audio_device_->SampleRate(); SendLogMessage(String::Format( "%s => (no resampling: context sample rate set to %0.f Hz)", __func__, context_sample_rate_)); } + // Record the sizes if we successfully created an output device. + // Histogram for audioHardwareBufferSize + base::UmaHistogramSparse( + "WebAudio.AudioDestination.HardwareBufferSize", + static_cast<int>(Platform::Current()->AudioHardwareBufferSize())); + + // Histogram for the actual callback size used. Typically, this is the same + // as audioHardwareBufferSize, but can be adjusted depending on some + // heuristics below. + base::UmaHistogramSparse("WebAudio.AudioDestination.CallbackBufferSize", + callback_buffer_size_); + base::UmaHistogramSparse("WebAudio.AudioContext.HardwareSampleRate", web_audio_device_->SampleRate()); @@ -366,7 +373,7 @@ // the most common ratios to be the set 0.5, 44100/48000, and 48000/44100. // Other values are possible but seem unlikely. base::UmaHistogramSparse("WebAudio.AudioContextOptions.sampleRateRatio", - static_cast<int32_t>(100 * scale_factor + 0.5)); + static_cast<int32_t>(100.0 * scale_factor + 0.5)); } } @@ -451,25 +458,6 @@ metric_reporter_.GetMetric()); } -bool AudioDestination::CheckBufferSize(unsigned render_quantum_frames) { - // Record the sizes if we successfully created an output device. - // Histogram for audioHardwareBufferSize - base::UmaHistogramSparse("WebAudio.AudioDestination.HardwareBufferSize", - static_cast<int>(HardwareBufferSize())); - - // Histogram for the actual callback size used. Typically, this is the same - // as audioHardwareBufferSize, but can be adjusted depending on some - // heuristics below. - base::UmaHistogramSparse("WebAudio.AudioDestination.CallbackBufferSize", - callback_buffer_size_); - - // Check if the requested buffer size is too large. - const bool is_buffer_size_valid = - callback_buffer_size_ + render_quantum_frames <= kFIFOSize; - DCHECK_LE(callback_buffer_size_ + render_quantum_frames, kFIFOSize); - return is_buffer_size_valid; -} - void AudioDestination::SendLogMessage(const String& message) const { WebRtcLogMessage(String::Format("[WA]AD::%s [state=%s]", message.Utf8().c_str(),
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.h b/third_party/blink/renderer/platform/audio/audio_destination.h index 76df5cd..347cae2 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.h +++ b/third_party/blink/renderer/platform/audio/audio_destination.h
@@ -104,27 +104,23 @@ void StartWithWorkletTaskRunner( scoped_refptr<base::SingleThreadTaskRunner> worklet_task_runner); - // Getters must be accessed from the main thread. - uint32_t CallbackBufferSize() const; - bool IsPlaying(); // This is the context sample rate, not the device one. double SampleRate() const; + uint32_t CallbackBufferSize() const; + // Returns the audio buffer size in frames used by the underlying audio // hardware. int FramesPerBuffer() const; // The information from the actual audio hardware. (via Platform::Current) - static size_t HardwareBufferSize(); - static float HardwareSampleRate(); static uint32_t MaxChannelCount(); // Sets the detect silence flag for `web_audio_device_`. void SetDetectSilence(bool detect_silence); - // This should only be called from the audio thread. unsigned RenderQuantumFrames() const; private: @@ -148,22 +144,19 @@ // Provide input to the resampler (if used). void ProvideResamplerInput(int resampler_frame_delay, AudioBus* dest); - // Check if the buffer size chosen by the WebAudioDevice is too large. - bool CheckBufferSize(unsigned render_quantum_frames); - void SendLogMessage(const String& message) const; // Accessed by the main thread. std::unique_ptr<WebAudioDevice> web_audio_device_; - uint32_t callback_buffer_size_; + const uint32_t callback_buffer_size_; const unsigned number_of_output_channels_; const unsigned render_quantum_frames_; // The sample rate used for rendering the Web Audio graph. - float context_sample_rate_; + const float context_sample_rate_; // Can be accessed by both threads: resolves the buffer size mismatch between // the WebAudio engine and the callback function from the actual audio device.
diff --git a/third_party/blink/tools/blinkpy/web_tests/results.html b/third_party/blink/tools/blinkpy/web_tests/results.html index a0970fb..40809236 100644 --- a/third_party/blink/tools/blinkpy/web_tests/results.html +++ b/third_party/blink/tools/blinkpy/web_tests/results.html
@@ -548,7 +548,7 @@ '-expected.png': 'expected_image', '-diff.png': 'image_diff', '-actual.txt': 'actual_text', - '-expected.txt': 'expected_txt', + '-expected.txt': 'expected_text', '-diff.txt': 'text_diff', '-pretty-diff.html': 'pretty_text_diff', '-actual.wav': 'actual_audio', @@ -585,7 +585,7 @@ return this.dir + this.resultPrefix + resultName; } let artifacts = await this.getArtifacts(); - return artifacts[PathParser.resultNameToArtifactName[resultName]]; + return artifacts[PathParser.resultNameToArtifactName[resultName]] || 'about:blank'; } resultFilename(resultName) { @@ -2944,6 +2944,19 @@ let script = document.createElement('script'); script.src = jsonpUrl.substring(slashPos + 1); + script.onerror = () => { + let message = `Fail to load ${jsonpUrl}.<br>` + + 'This may be because the web test step has not finished yet'; + if (location.search) { + let oldResults = + `https://test-results.appspot.com/data/layout_results/${jsonpUrl.substring(0, slashPos)}/layout-test-results/results.html`; + message += ', or the results are in the old format which can be' + + ` accessed through <a href="${oldResults}">this link</a>.`; + } else { + message += '.'; + } + document.write(message); + }; document.body.appendChild(script); })(); </script>
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 36e06c76..175a91a8 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6306,7 +6306,8 @@ # Sheriff 2022-10-03 crbug.com/1368767 wpt_internal/webmidi/requestmidiaccess-basic.https.html [ Failure Pass ] -crbug.com/1394227 [ Linux ] external/wpt/element-timing/image-src-change.html [ Failure Pass ] +# TODO(crbug.com/1403318): Re-enable this test +crbug.com/1394227 [ Linux ] external/wpt/element-timing/image-src-change.html [ Failure Skip ] crbug.com/1394227 [ Mac ] external/wpt/element-timing/image-src-change.html [ Failure Pass ] # These tests are optional and not reliably supported in Chrome.
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index fe15e91e..259311d 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1685,7 +1685,17 @@ "prefix": "js-resizable-arraybuffer", "platforms": ["Linux", "Mac", "Win"], "bases": [ - "external/wpt/html/infrastructure/safe-passing-of-structured-data/cross-origin-transfer-resizable-arraybuffer.html" + "external/wpt/html/infrastructure/safe-passing-of-structured-data/cross-origin-transfer-resizable-arraybuffer.html", + "external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.html", + "external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker.html", + "external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker.html", + "external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker.html", + "external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.html", + "external/wpt/html/webappapis/structured-clone/structured-clone.any.html", + "external/wpt/html/webappapis/structured-clone/structured-clone.any.worker.html", + "external/wpt/webidl/ecmascript-binding/allow-resizable.html", + "external/wpt/workers/semantics/structured-clone/dedicated.html", + "external/wpt/workers/semantics/structured-clone/shared.html" ], "exclusive_tests": [ "external/wpt/html/infrastructure/safe-passing-of-structured-data/cross-origin-transfer-resizable-arraybuffer.html"
diff --git a/third_party/blink/web_tests/external/wpt/common/sab.js b/third_party/blink/web_tests/external/wpt/common/sab.js index 47d1297..a3ea610e 100644 --- a/third_party/blink/web_tests/external/wpt/common/sab.js +++ b/third_party/blink/web_tests/external/wpt/common/sab.js
@@ -6,14 +6,14 @@ } catch(e) { sabConstructor = null; } - return (type, length) => { + return (type, length, opts) => { if (type === "ArrayBuffer") { - return new ArrayBuffer(length); + return new ArrayBuffer(length, opts); } else if (type === "SharedArrayBuffer") { if (sabConstructor && sabConstructor.name !== "SharedArrayBuffer") { throw new Error("WebAssembly.Memory does not support shared:true"); } - return new sabConstructor(length); + return new sabConstructor(length, opts); } else { throw new Error("type has to be ArrayBuffer or SharedArrayBuffer"); }
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any-expected.txt new file mode 100644 index 0000000..09b51b19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any-expected.txt
@@ -0,0 +1,154 @@ +This is a testharness.js-based test. +Found 150 tests; 139 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js index 1814df3..6ba17f7 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.js
@@ -1,4 +1,5 @@ // META: global=window,worker +// META: script=/common/sab.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker-expected.txt new file mode 100644 index 0000000..acb3995 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker-expected.txt
@@ -0,0 +1,139 @@ +This is a testharness.js-based test. +Found 135 tests; 124 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker-expected.txt new file mode 100644 index 0000000..acb3995 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker-expected.txt
@@ -0,0 +1,139 @@ +This is a testharness.js-based test. +Found 135 tests; 124 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker-expected.txt new file mode 100644 index 0000000..acb3995 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker-expected.txt
@@ -0,0 +1,139 @@ +This is a testharness.js-based test. +Found 135 tests; 124 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window-expected.txt new file mode 100644 index 0000000..09b51b19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window-expected.txt
@@ -0,0 +1,154 @@ +This is a testharness.js-based test. +Found 150 tests; 139 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js index ebbda99..2a46d79 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window.js
@@ -1,3 +1,4 @@ +// META: script=/common/sab.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js index 65e4085..23cf4f6 100644 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js
@@ -97,3 +97,73 @@ assert_equals(Object.getPrototypeOf(transfer), ReadableStream.prototype); } }); + +structuredCloneBatteryOfTests.push({ + description: 'Resizable ArrayBuffer is transferable', + async f(runner) { + const buffer = new ArrayBuffer(16, { maxByteLength: 1024 }); + const copy = await runner.structuredClone(buffer, [buffer]); + assert_equals(buffer.byteLength, 0); + assert_equals(copy.byteLength, 16); + assert_equals(copy.maxByteLength, 1024); + assert_true(copy.resizable); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Length-tracking TypedArray is transferable', + async f(runner) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const ta = new Uint8Array(ab); + const copy = await runner.structuredClone(ta, [ab]); + assert_equals(ab.byteLength, 0); + assert_equals(copy.buffer.byteLength, 16); + assert_equals(copy.buffer.maxByteLength, 1024); + assert_true(copy.buffer.resizable); + copy.buffer.resize(32); + assert_equals(copy.byteLength, 32); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Length-tracking DataView is transferable', + async f(runner) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const dv = new DataView(ab); + const copy = await runner.structuredClone(dv, [ab]); + assert_equals(ab.byteLength, 0); + assert_equals(copy.buffer.byteLength, 16); + assert_equals(copy.buffer.maxByteLength, 1024); + assert_true(copy.buffer.resizable); + copy.buffer.resize(32); + assert_equals(copy.byteLength, 32); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Transferring OOB TypedArray throws', + async f(runner, t) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const ta = new Uint8Array(ab, 8); + ab.resize(0); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(ta, [ab]) + ); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Transferring OOB DataView throws', + async f(runner, t) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const dv = new DataView(ab, 8); + ab.resize(0); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(dv, [ab]) + ); + } +});
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests.js b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests.js index 580a81a..923ac9d 100644 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests.js +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone-battery-of-tests.js
@@ -379,6 +379,14 @@ check('Array FileList object, FileList empty', () => ([func_FileList_empty()]), compare_Array(enumerate_props(compare_FileList)), true); check('Object FileList object, FileList empty', () => ({'x':func_FileList_empty()}), compare_Object(enumerate_props(compare_FileList)), true); +function compare_ArrayBuffer(actual, input) { + assert_true(actual instanceof ArrayBuffer, 'instanceof ArrayBuffer'); + assert_equals(actual.byteLength, input.byteLength, 'byteLength'); + assert_equals(actual.maxByteLength, input.maxByteLength, 'maxByteLength'); + assert_equals(actual.resizable, input.resizable, 'resizable'); + assert_equals(actual.growable, input.growable, 'growable'); +} + function compare_ArrayBufferView(view) { const Type = self[view]; return function(actual, input) { @@ -386,6 +394,8 @@ assert_unreached(actual); assert_true(actual instanceof Type, 'instanceof '+view); assert_equals(actual.length, input.length, 'length'); + assert_equals(actual.byteLength, input.byteLength, 'byteLength'); + assert_equals(actual.byteOffset, input.byteOffset, 'byteOffset'); assert_not_equals(actual.buffer, input.buffer, 'buffer'); for (let i = 0; i < actual.length; ++i) { assert_equals(actual[i], input[i], 'actual['+i+']'); @@ -667,3 +677,77 @@ assert_equals(Object.getPrototypeOf(copy), File.prototype); } ); + +check( + 'Resizable ArrayBuffer', + () => { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + assert_true(ab.resizable); + return ab; + }, + compare_ArrayBuffer); + +structuredCloneBatteryOfTests.push({ + description: 'Growable SharedArrayBuffer', + async f(runner) { + const sab = createBuffer('SharedArrayBuffer', 16, { maxByteLength: 1024 }); + assert_true(sab.growable); + try { + const copy = await runner.structuredClone(sab); + compare_ArrayBuffer(sab, copy); + } catch (e) { + // If we're cross-origin isolated, cloning SABs should not fail. + if (e instanceof DOMException && e.code === DOMException.DATA_CLONE_ERR) { + assert_false(self.crossOriginIsolated); + } else { + throw e; + } + } + } +}); + +check( + 'Length-tracking TypedArray', + () => { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + assert_true(ab.resizable); + return new Uint8Array(ab); + }, + compare_ArrayBufferView('Uint8Array')); + +check( + 'Length-tracking DataView', + () => { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + assert_true(ab.resizable); + return new DataView(ab); + }, + compare_ArrayBufferView('DataView')); + +structuredCloneBatteryOfTests.push({ + description: 'Serializing OOB TypedArray throws', + async f(runner, t) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const ta = new Uint8Array(ab, 8); + ab.resize(0); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(ta) + ); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Serializing OOB DataView throws', + async f(runner, t) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const dv = new DataView(ab, 8); + ab.resize(0); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(dv) + ); + } +});
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any-expected.txt b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any-expected.txt new file mode 100644 index 0000000..09b51b19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any-expected.txt
@@ -0,0 +1,154 @@ +This is a testharness.js-based test. +Found 150 tests; 139 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.js b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.js index 90ba5df..1358a71 100644 --- a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.js +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.js
@@ -1,4 +1,5 @@ // META: title=structuredClone() tests +// META: script=/common/sab.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js // META: script=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.worker-expected.txt new file mode 100644 index 0000000..acb3995 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/structured-clone/structured-clone.any.worker-expected.txt
@@ -0,0 +1,139 @@ +This is a testharness.js-based test. +Found 135 tests; 124 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/allow-resizable-expected.txt b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/allow-resizable-expected.txt new file mode 100644 index 0000000..a3f42be --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/allow-resizable-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +FAIL APIs without [AllowResizable] throw when passed resizable ArrayBuffers assert_throws_js: function "() => { + new Response(new Uint8Array(rab)); + }" did not throw +FAIL APIs with [AllowShared] but without [AllowResizable] throw when passed growable SharedArrayBuffers Failed to execute 'encodeInto' on 'TextEncoder': The provided Uint8Array value must not be shared. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/allow-resizable.html b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/allow-resizable.html new file mode 100644 index 0000000..be9df55 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/allow-resizable.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/sab.js"></script> +<script type="module"> +test(t => { + // Fixed-length ABs should not throw + const ab = new ArrayBuffer(16); + new Response(new Uint8Array(ab)); + + const rab = new ArrayBuffer(16, { maxByteLength: 1024 }); + // Response doesn't have [AllowResizable] or [AllowShared] + assert_throws_js(TypeError, () => { + new Response(new Uint8Array(rab)); + }); +}, "APIs without [AllowResizable] throw when passed resizable ArrayBuffers"); + +test(t => { + const enc = new TextEncoder(); + + // Fixed-length SABs should not throw + const sab = createBuffer('SharedArrayBuffer', 16, { maxByteLength: 1024 }); + enc.encodeInto("foobar", new Uint8Array(sab)); + + const gsab = createBuffer('SharedArrayBuffer', 16, { maxByteLength: 1024 }); + // TextEncoder.encodeInto doesn't have [AllowResizable] but has [AllowShared] + assert_throws_js(TypeError, () => { + enc.encodeInto("foobar", new Uint8Array(gsab)); + }); +}, "APIs with [AllowShared] but without [AllowResizable] throw when passed growable SharedArrayBuffers"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt new file mode 100644 index 0000000..09b51b19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt
@@ -0,0 +1,154 @@ +This is a testharness.js-based test. +Found 150 tests; 139 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated.html b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated.html index 2f1732c..16b6be5 100644 --- a/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated.html +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/dedicated.html
@@ -2,6 +2,7 @@ <title>structured clone to dedicated worker</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src=/common/sab.js></script> <script src=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js></script> <script src=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js></script> <script src=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js></script>
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared-expected.txt b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared-expected.txt new file mode 100644 index 0000000..09b51b19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared-expected.txt
@@ -0,0 +1,154 @@ +This is a testharness.js-based test. +Found 150 tests; 139 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +FAIL Resizable ArrayBuffer assert_true: expected true got undefined +FAIL Growable SharedArrayBuffer assert_true: expected true got undefined +FAIL Length-tracking TypedArray assert_true: expected true got undefined +FAIL Length-tracking DataView assert_true: expected true got undefined +FAIL Serializing OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Serializing OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +FAIL Resizable ArrayBuffer is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking TypedArray is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Length-tracking DataView is transferable assert_equals: expected (number) 1024 but got (undefined) undefined +FAIL Transferring OOB TypedArray throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +FAIL Transferring OOB DataView throws promise_test: Unhandled rejection with value: object "TypeError: ab.resize is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared.html b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared.html index 793da8f..eb85499f 100644 --- a/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared.html +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/structured-clone/shared.html
@@ -2,6 +2,7 @@ <title>structured clone to shared worker</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src=/common/sab.js></script> <script src=/html/webappapis/structured-clone/structured-clone-battery-of-tests.js></script> <script src=/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js></script> <script src=/html/webappapis/structured-clone/structured-clone-battery-of-tests-harness.js></script>
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any-expected.txt new file mode 100644 index 0000000..5ccf001 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any-expected.txt
@@ -0,0 +1,153 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker-expected.txt new file mode 100644 index 0000000..77eb14338 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.serviceworker-expected.txt
@@ -0,0 +1,138 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker-expected.txt new file mode 100644 index 0000000..77eb14338 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.sharedworker-expected.txt
@@ -0,0 +1,138 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker-expected.txt new file mode 100644 index 0000000..77eb14338 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/messagechannel.any.worker-expected.txt
@@ -0,0 +1,138 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window-expected.txt new file mode 100644 index 0000000..5ccf001 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/window-postmessage.window-expected.txt
@@ -0,0 +1,153 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/webappapis/structured-clone/structured-clone.any-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/webappapis/structured-clone/structured-clone.any-expected.txt new file mode 100644 index 0000000..5ccf001 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/webappapis/structured-clone/structured-clone.any-expected.txt
@@ -0,0 +1,153 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/webappapis/structured-clone/structured-clone.any.worker-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/webappapis/structured-clone/structured-clone.any.worker-expected.txt new file mode 100644 index 0000000..77eb14338 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/html/webappapis/structured-clone/structured-clone.any.worker-expected.txt
@@ -0,0 +1,138 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/webidl/ecmascript-binding/README.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/webidl/ecmascript-binding/README.txt new file mode 100644 index 0000000..3eaae58 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/webidl/ecmascript-binding/README.txt
@@ -0,0 +1 @@ +This virtual test suite will be removed once resizable ArrayBuffers ship in V8.
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/webidl/ecmascript-binding/allow-resizable-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/webidl/ecmascript-binding/allow-resizable-expected.txt new file mode 100644 index 0000000..3db7e63 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/webidl/ecmascript-binding/allow-resizable-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS APIs without [AllowResizable] throw when passed resizable ArrayBuffers +FAIL APIs with [AllowShared] but without [AllowResizable] throw when passed growable SharedArrayBuffers Failed to execute 'encodeInto' on 'TextEncoder': The provided Uint8Array value must not be shared. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/README.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/README.txt new file mode 100644 index 0000000..3eaae58 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/README.txt
@@ -0,0 +1 @@ +This virtual test suite will be removed once resizable ArrayBuffers ship in V8.
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt new file mode 100644 index 0000000..5ccf001 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/dedicated-expected.txt
@@ -0,0 +1,153 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/shared-expected.txt b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/shared-expected.txt new file mode 100644 index 0000000..5ccf001 --- /dev/null +++ b/third_party/blink/web_tests/virtual/js-resizable-arraybuffer/external/wpt/workers/semantics/structured-clone/shared-expected.txt
@@ -0,0 +1,153 @@ +This is a testharness.js-based test. +PASS primitive undefined +PASS primitive null +PASS primitive true +PASS primitive false +PASS primitive string, empty string +PASS primitive string, lone high surrogate +PASS primitive string, lone low surrogate +PASS primitive string, NUL +PASS primitive string, astral character +PASS primitive number, 0.2 +PASS primitive number, 0 +PASS primitive number, -0 +PASS primitive number, NaN +PASS primitive number, Infinity +PASS primitive number, -Infinity +PASS primitive number, 9007199254740992 +PASS primitive number, -9007199254740992 +PASS primitive number, 9007199254740994 +PASS primitive number, -9007199254740994 +PASS primitive BigInt, 0n +PASS primitive BigInt, -0n +PASS primitive BigInt, -9007199254740994000n +PASS primitive BigInt, -9007199254740994000900719925474099400090071992547409940009007199254740994000n +PASS Array primitives +PASS Object primitives +PASS Boolean true +PASS Boolean false +PASS Array Boolean objects +PASS Object Boolean objects +PASS String empty string +PASS String lone high surrogate +PASS String lone low surrogate +PASS String NUL +PASS String astral character +PASS Array String objects +PASS Object String objects +PASS Number 0.2 +PASS Number 0 +PASS Number -0 +PASS Number NaN +PASS Number Infinity +PASS Number -Infinity +PASS Number 9007199254740992 +PASS Number -9007199254740992 +PASS Number 9007199254740994 +PASS Number -9007199254740994 +PASS BigInt -9007199254740994n +PASS Array Number objects +PASS Object Number objects +PASS Date 0 +PASS Date -0 +PASS Date -8.64e15 +PASS Date 8.64e15 +PASS Array Date objects +PASS Object Date objects +PASS RegExp flags and lastIndex +PASS RegExp sticky flag +PASS RegExp unicode flag +PASS RegExp empty +PASS RegExp slash +PASS RegExp new line +PASS Array RegExp object, RegExp flags and lastIndex +PASS Array RegExp object, RegExp sticky flag +PASS Array RegExp object, RegExp unicode flag +PASS Array RegExp object, RegExp empty +PASS Array RegExp object, RegExp slash +PASS Array RegExp object, RegExp new line +PASS Object RegExp object, RegExp flags and lastIndex +PASS Object RegExp object, RegExp sticky flag +PASS Object RegExp object, RegExp unicode flag +PASS Object RegExp object, RegExp empty +PASS Object RegExp object, RegExp slash +PASS Object RegExp object, RegExp new line +PASS Empty Error object +PASS Error object +PASS EvalError object +PASS RangeError object +PASS ReferenceError object +PASS SyntaxError object +PASS TypeError object +PASS URIError object +PASS Blob basic +PASS Blob unpaired high surrogate (invalid utf-8) +PASS Blob unpaired low surrogate (invalid utf-8) +PASS Blob paired surrogates (invalid utf-8) +PASS Blob empty +PASS Blob NUL +PASS Array Blob object, Blob basic +PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Array Blob object, Blob paired surrogates (invalid utf-8) +PASS Array Blob object, Blob empty +PASS Array Blob object, Blob NUL +PASS Array Blob object, two Blobs +PASS Object Blob object, Blob basic +PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) +PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) +PASS Object Blob object, Blob paired surrogates (invalid utf-8) +PASS Object Blob object, Blob empty +PASS Object Blob object, Blob NUL +PASS File basic +PASS FileList empty +PASS Array FileList object, FileList empty +PASS Object FileList object, FileList empty +PASS ImageData 1x1 transparent black +PASS ImageData 1x1 non-transparent non-black +PASS Array ImageData object, ImageData 1x1 transparent black +PASS Array ImageData object, ImageData 1x1 non-transparent non-black +PASS Object ImageData object, ImageData 1x1 transparent black +PASS Object ImageData object, ImageData 1x1 non-transparent non-black +PASS Array sparse +PASS Array with non-index property +PASS Object with index property and length +PASS Array with circular reference +PASS Object with circular reference +PASS Array with identical property values +PASS Object with identical property values +PASS Object with property on prototype +PASS Object with non-enumerable property +PASS Object with non-writable property +PASS Object with non-configurable property +PASS Object with a getter that throws +PASS ImageBitmap 1x1 transparent black +PASS ImageBitmap 1x1 non-transparent non-black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black +PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black +PASS ObjectPrototype must lose its exotic-ness when cloned +PASS Serializing a non-serializable platform object fails +PASS An object whose interface is deleted from the global must still deserialize +PASS A subclass instance will deserialize as its closest serializable superclass +PASS Resizable ArrayBuffer +PASS Growable SharedArrayBuffer +PASS Length-tracking TypedArray +PASS Length-tracking DataView +PASS Serializing OOB TypedArray throws +PASS Serializing OOB DataView throws +PASS ArrayBuffer +PASS MessagePort +PASS A detached ArrayBuffer cannot be transferred +PASS A detached platform object cannot be transferred +PASS Transferring a non-transferable platform object fails +PASS An object whose interface is deleted from the global object must still be received +PASS A subclass instance will be received as its closest transferable superclass +PASS Resizable ArrayBuffer is transferable +PASS Length-tracking TypedArray is transferable +PASS Length-tracking DataView is transferable +PASS Transferring OOB TypedArray throws +PASS Transferring OOB DataView throws +Harness: the test ran to completion. +
diff --git a/third_party/wpt_tools/README.chromium b/third_party/wpt_tools/README.chromium index cb933a2..55308376 100644 --- a/third_party/wpt_tools/README.chromium +++ b/third_party/wpt_tools/README.chromium
@@ -1,7 +1,7 @@ Name: web-platform-tests - Test Suites for Web Platform specifications Short Name: wpt URL: https://github.com/web-platform-tests/wpt/ -Version: 4f5b32625ce798e1404df06ddd75677e01c7fdbb +Version: c30037b8fc2efe7fc7a4c0bba20d274fdbde5537 License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html) License File: NOT_SHIPPED Security Critical: no
diff --git a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py index bb81b426c..9e8737e 100644 --- a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py +++ b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py
@@ -11,10 +11,9 @@ # TODO: Match on error and let it be a class variables only. error_code = None # type: ClassVar[str] - def __init__(self, error: str, message: str, stacktrace: Optional[str]): + def __init__(self, message: str, stacktrace: Optional[str] = None): super() - self.error = error self.message = message self.stacktrace = stacktrace @@ -24,9 +23,9 @@ def __str__(self): """Return the string representation of the object.""" - message = f"{self.error} ({self.message})" + message = f"{self.error_code} ({self.message})" - if self.stacktrace: + if self.stacktrace is not None: message += f"\n\nRemote-end stacktrace:\n\n{self.stacktrace}" return message @@ -54,7 +53,7 @@ Defaults to ``UnknownErrorException`` if `error` is unknown. """ cls = get(error) - return cls(error, message, stacktrace) + return cls(message, stacktrace) def get(error_code: str) -> Type[BidiException]:
diff --git a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/script.py b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/script.py index 8bdbd30a..d9af11a 100644 --- a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/script.py +++ b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/script.py
@@ -1,6 +1,7 @@ from enum import Enum -from typing import Any, Optional, Mapping, List, MutableMapping, Union, Dict +from typing import Any, Dict, List, Mapping, MutableMapping, Optional, Union +from ..error import UnknownErrorException from ._module import BidiModule, command @@ -69,9 +70,14 @@ @call_function.result def _call_function(self, result: Mapping[str, Any]) -> Any: - if "result" not in result: + assert "type" in result + + if result["type"] == "success": + return result["result"] + elif result["type"] == "exception": raise ScriptEvaluateResultException(result) - return result["result"] + else: + raise UnknownErrorException(f"""Invalid type '{result["type"]}' in response""") @command def disown(self, handles: List[str], target: Target) -> Mapping[str, Any]: @@ -98,9 +104,14 @@ @evaluate.result def _evaluate(self, result: Mapping[str, Any]) -> Any: - if "result" not in result: + assert "type" in result + + if result["type"] == "success": + return result["result"] + elif result["type"] == "exception": raise ScriptEvaluateResultException(result) - return result["result"] + else: + raise UnknownErrorException(f"""Invalid type '{result["type"]}' in response""") @command def get_realms(
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py index 0df90990..89aaf003 100644 --- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py +++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py
@@ -180,16 +180,18 @@ def __init__(self, logger, browser, server_config, binary=None, timeout_multiplier=1, screenshot_cache=None, debug_info=None, pause_after_test=False, - **kwargs): + reftest_screenshot="unexpected", **kwargs): ProcessTestExecutor.__init__(self, logger, browser, server_config, timeout_multiplier=timeout_multiplier, - debug_info=debug_info) + debug_info=debug_info, + reftest_screenshot=reftest_screenshot) self.protocol = ConnectionlessProtocol(self, browser) self.screenshot_cache = screenshot_cache + self.reftest_screenshot = reftest_screenshot self.implementation = RefTestImplementation(self) self.tempdir = tempfile.mkdtemp() self.hosts_path = write_hosts_file(server_config)
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py index f1724d35..9ac6249c 100644 --- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py +++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
@@ -357,7 +357,7 @@ output_results=True, **kwargs): kwargs_extras = [{}] if chaos_mode and kwargs["product"] == "firefox": - kwargs_extras.append({"chaos_mode_flags": "0xfb"}) + kwargs_extras.append({"chaos_mode_flags": int("0xfb", base=16)}) steps = get_steps(logger, repeat_loop, repeat_restart, kwargs_extras)
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py index 61af18c..82ffc9b 100644 --- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py +++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
@@ -333,9 +333,8 @@ self.logger = None self.test_count = 0 - self.unexpected_count = 0 - self.unexpected_pass_count = 0 self.unexpected_tests = set() + self.unexpected_pass_tests = set() # This may not really be what we want self.daemon = True @@ -651,21 +650,22 @@ # Write the result of each subtest file_result, test_results = results subtest_unexpected = False + subtest_all_pass_or_expected = True for result in test_results: if test.disabled(result.name): continue expected = test.expected(result.name) known_intermittent = test.known_intermittent(result.name) is_unexpected = expected != result.status and result.status not in known_intermittent + is_expected_notrun = (expected == "NOTRUN" or "NOTRUN" in known_intermittent) if is_unexpected: - self.unexpected_count += 1 - self.logger.debug("Unexpected count in this thread %i" % self.unexpected_count) subtest_unexpected = True - is_unexpected_pass = is_unexpected and result.status == "PASS" - if is_unexpected_pass: - self.unexpected_pass_count += 1 + if result.status != "PASS" and not is_expected_notrun: + # Any result against an expected "NOTRUN" should be treated + # as unexpected pass. + subtest_all_pass_or_expected = False self.logger.test_status(test.id, result.name, @@ -698,17 +698,19 @@ self.test_count += 1 is_unexpected = expected != status and status not in known_intermittent - if is_unexpected: - self.unexpected_count += 1 - self.logger.debug("Unexpected count in this thread %i" % self.unexpected_count) - - is_unexpected_pass = is_unexpected and status == "OK" - if is_unexpected_pass: - self.unexpected_pass_count += 1 if is_unexpected or subtest_unexpected: self.unexpected_tests.add(test.id) + # A result is unexpected pass if the test or any subtest run + # unexpectedly, and the overall status is OK (for test harness test), or + # PASS (for reftest), and all unexpected results for subtests (if any) are + # unexpected pass. + is_unexpected_pass = ((is_unexpected or subtest_unexpected) and + status in ["OK", "PASS"] and subtest_all_pass_or_expected) + if is_unexpected_pass: + self.unexpected_pass_tests.add(test.id) + if "assertion_count" in file_result.extra: assertion_count = file_result.extra["assertion_count"] if assertion_count is not None and assertion_count > 0: @@ -975,11 +977,8 @@ def test_count(self): return sum(manager.test_count for manager in self.pool) - def unexpected_count(self): - return sum(manager.unexpected_count for manager in self.pool) - - def unexpected_pass_count(self): - return sum(manager.unexpected_pass_count for manager in self.pool) - def unexpected_tests(self): return set().union(*(manager.unexpected_tests for manager in self.pool)) + + def unexpected_pass_tests(self): + return set().union(*(manager.unexpected_pass_tests for manager in self.pool))
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py index eec0130..2fe6586 100644 --- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py +++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py
@@ -184,11 +184,9 @@ debugging_group.add_argument("--repeat-until-unexpected", action="store_true", default=None, help="Run tests in a loop until one returns an unexpected result") debugging_group.add_argument('--retry-unexpected', type=int, default=0, - help=('Maximum number of times to retry ' - 'each test that consistently runs ' - 'unexpectedly in the initial repeat ' - 'loop. A retried test takes any ' - 'expected status as its final result.')) + help=('Maximum number of times to retry unexpected tests. ' + 'A test is retried until it gets one of the expected status, ' + 'or until it exhausts the maximum number of retries.')) debugging_group.add_argument('--pause-after-test', action="store_true", default=None, help="Halt the test runner after each test (this happens by default if only a single test is run)") debugging_group.add_argument('--no-pause-after-test', dest="pause_after_test", action="store_false",
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py index e879925..548d5bf 100644 --- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py +++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py
@@ -158,7 +158,7 @@ def run_test_iteration(test_status, test_loader, test_source_kwargs, test_source_cls, run_info, recording, test_environment, product, run_test_kwargs): """Runs the entire test suite. - This is called for each repeat or retry run requested.""" + This is called for each repeat run requested.""" tests_by_type = defaultdict(list) for test_type in test_loader.test_types: tests_by_type[test_type].extend(test_loader.tests[test_type]) @@ -170,12 +170,7 @@ logger.critical("Loading tests failed") return False - if test_status.retries_remaining: - for test_type, tests in dict(test_groups).items(): - test_groups[test_type] = [test for test in tests - if test in test_status.unexpected_tests] - - logger.suite_start(test_groups, + logger.suite_start(tests_by_type, name='web-platform-test', run_info=run_info, extra={"run_by_dir": run_test_kwargs["run_by_dir"]}) @@ -226,38 +221,56 @@ else: tests_to_run[test_type] = test_loader.tests[test_type] - if test_status.retries_remaining: - tests_to_run[test_type] = [test for test in tests_to_run[test_type] - if test.id in test_status.unexpected_tests] - + unexpected_tests = set() + unexpected_pass_tests = set() recording.pause() - with ManagerGroup("web-platform-tests", - run_test_kwargs["processes"], - test_source_cls, - test_source_kwargs, - test_implementation_by_type, - run_test_kwargs["rerun"], - run_test_kwargs["pause_after_test"], - run_test_kwargs["pause_on_unexpected"], - run_test_kwargs["restart_on_unexpected"], - run_test_kwargs["debug_info"], - not run_test_kwargs["no_capture_stdio"], - run_test_kwargs["restart_on_new_group"], - recording=recording) as manager_group: - try: - manager_group.run(tests_to_run) - except KeyboardInterrupt: - logger.critical("Main thread got signal") - manager_group.stop() - raise - test_status.total_tests += manager_group.test_count() - test_status.unexpected += manager_group.unexpected_count() - test_status.unexpected_pass += manager_group.unexpected_pass_count() + retry_counts = run_test_kwargs["retry_unexpected"] + for i in range(retry_counts + 1): + if i > 0: + if not run_test_kwargs["fail_on_unexpected_pass"]: + unexpected_fail_tests = unexpected_tests - unexpected_pass_tests + else: + unexpected_fail_tests = unexpected_tests + if len(unexpected_fail_tests) == 0: + break + for test_type, tests in tests_to_run.items(): + tests_to_run[test_type] = [test for test in tests + if test.id in unexpected_fail_tests] - if test_status.repeated_runs == 1: - test_status.unexpected_tests = manager_group.unexpected_tests() - else: - test_status.unexpected_tests &= manager_group.unexpected_tests() + logger.suite_end() + logger.suite_start(tests_to_run, + name='web-platform-test', + run_info=run_info, + extra={"run_by_dir": run_test_kwargs["run_by_dir"]}) + + with ManagerGroup("web-platform-tests", + run_test_kwargs["processes"], + test_source_cls, + test_source_kwargs, + test_implementation_by_type, + run_test_kwargs["rerun"], + run_test_kwargs["pause_after_test"], + run_test_kwargs["pause_on_unexpected"], + run_test_kwargs["restart_on_unexpected"], + run_test_kwargs["debug_info"], + not run_test_kwargs["no_capture_stdio"], + run_test_kwargs["restart_on_new_group"], + recording=recording) as manager_group: + try: + manager_group.run(tests_to_run) + except KeyboardInterrupt: + logger.critical("Main thread got signal") + manager_group.stop() + raise + + test_status.total_tests += manager_group.test_count() + unexpected_tests = manager_group.unexpected_tests() + unexpected_pass_tests = manager_group.unexpected_pass_tests() + + test_status.unexpected += len(unexpected_tests) + test_status.unexpected_pass += len(unexpected_pass_tests) + + logger.suite_end() return True @@ -299,8 +312,6 @@ self.repeated_runs = 0 self.expected_repeated_runs = 0 self.all_skipped = False - self.unexpected_tests = set() - self.retries_remaining = 0 def run_tests(config, test_paths, product, **kwargs): @@ -433,7 +444,6 @@ recording.set(["after-end"]) logger.info(f"Got {test_status.unexpected} unexpected results, " f"with {test_status.unexpected_pass} unexpected passes") - logger.suite_end() # Note this iteration's runtime iteration_runtime = datetime.now() - iteration_start @@ -447,44 +457,10 @@ test_status.all_skipped = True break - if not test_status.all_skipped and kwargs["retry_unexpected"] > 0: - retry_success = retry_unexpected_tests(test_status, test_loader, - test_source_kwargs, - test_source_cls, run_info, - recording, test_environment, - product, kwargs) - if not retry_success: - return False, test_status - # Return the evaluation of the runs and the number of repeated iterations that were run. return evaluate_runs(test_status, kwargs), test_status -def retry_unexpected_tests(test_status, test_loader, test_source_kwargs, - test_source_cls, run_info, recording, - test_environment, product, kwargs): - kwargs["rerun"] = 1 - max_retries = kwargs["retry_unexpected"] - test_status.retries_remaining = max_retries - while (test_status.retries_remaining > 0 and not - evaluate_runs(test_status, kwargs)): - logger.info(f"Retry {max_retries - test_status.retries_remaining + 1}") - test_status.total_tests = 0 - test_status.skipped = 0 - test_status.unexpected = 0 - test_status.unexpected_pass = 0 - iter_success = run_test_iteration(test_status, test_loader, - test_source_kwargs, test_source_cls, - run_info, recording, test_environment, - product, kwargs) - if not iter_success: - return False - recording.set(["after-end"]) - logger.suite_end() - test_status.retries_remaining -= 1 - return True - - def check_stability(**kwargs): from . import stability if kwargs["stability"]:
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index e2a6ff6..dc85d1f 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -288,7 +288,7 @@ "includes": [1925], }, "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/side_panel/customize_chrome/resources.grd": { - "META": {"sizes": {"includes": [30],}}, + "META": {"sizes": {"includes": [35],}}, "includes": [1930], }, "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/side_panel/side_panel_resources.grd": { @@ -448,6 +448,10 @@ "components/resources/dev_ui_components_resources.grd": { "includes": [2560], }, + "<(SHARED_INTERMEDIATE_DIR)/content/browser/resources/attribution_reporting/resources.grd": { + "META": {"sizes": {"includes": [20]}}, + "includes": [2565], + }, "<(SHARED_INTERMEDIATE_DIR)/content/browser/resources/indexed_db/resources.grd": { "META": {"sizes": {"includes": [20]}}, "includes": [2570],
diff --git a/tools/ipc_fuzzer/BUILD.gn b/tools/ipc_fuzzer/BUILD.gn index 1901b2e..21ca130 100644 --- a/tools/ipc_fuzzer/BUILD.gn +++ b/tools/ipc_fuzzer/BUILD.gn
@@ -13,10 +13,7 @@ if (is_win) { cflags = [ "/wd4366" ] } - defines = [ - "ENABLE_IPC_FUZZER", - "USE_CUPS", - ] + defines = [ "ENABLE_IPC_FUZZER" ] include_dirs = [ "." ] }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 477ec05..3ebd28e 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -63166,6 +63166,7 @@ label="OmniboxUIExperimentHideSuggestionUrlTrivialSubdomains:disabled"/> <int value="1387356699" label="PolicyAtomicGroup:enabled"/> <int value="1388726032" label="ChromeOSAmbientModeThrottleAnimation:enabled"/> + <int value="1389697465" label="OmniboxGroupingFramework:disabled"/> <int value="1389729816" label="data-reduction-proxy-lo-fi"/> <int value="1391313384" label="Hotspot:disabled"/> <int value="1392836587" label="DesktopPWAsElidedExtensionsMenu:disabled"/> @@ -63647,6 +63648,7 @@ <int value="1687272287" label="HandwritingLibraryDlc:disabled"/> <int value="1687544136" label="AndroidManagedByMenuItem:enabled"/> <int value="1687768359" label="ServiceWorkerBypassFetchHandler:disabled"/> + <int value="1687987218" label="OmniboxGroupingFramework:enabled"/> <int value="1688075820" label="OmniboxExperimentalKeywordMode:disabled"/> <int value="1689001971" label="ProjectorLocalPlayback:enabled"/> <int value="1689123607" label="enable-app-link"/> @@ -74846,6 +74848,27 @@ <int value="36" label="WorkerScriptLoader (Proxy)"/> </enum> +<enum name="OobeMultideviceScreenSkippedReason"> + <int value="0" label="Public session or ephermeral login"/> + <int value="1" label="Host phone already set"/> + <int value="2" label="Device sync finished and no eligible host phone found"/> + <int value="3" label="Setup client not initialized"/> + <int value="4" + label="Device sync not initialized during better together metadata + status fetch"/> + <int value="5" + label="Device sync not initialized during group private key status + fetch"/> + <int value="6" label="Encrypted metadata empty"/> + <int value="7" label="Waiting to receive group private key"/> + <int value="8" label="No encrypted group private key received"/> + <int value="9" label="Encrypted group private key empty"/> + <int value="10" label="Local device sync better together key missing"/> + <int value="11" label="Group private key decryption failed"/> + <int value="12" label="Screen destroyed before reason could be determined"/> + <int value="13" label="Unknown"/> +</enum> + <enum name="OobeUserClickTarget"> <int value="0" label="Shut down button"/> <int value="1" label="Browse as guest button"/> @@ -80184,10 +80207,10 @@ <int value="1" label="COPY_TO_NV12"> Copy to another NV12 texture that can be used in ANGLE. </int> - <int value="2" label="DELAYED_COPY_TO_NV12"> + <int value="2" label="DELAYED_COPY_TO_NV12 (Deprecated)"> Bind the resulting GLImage to the NV12 texture. If the texture's used in a an overlay than use it directly, otherwise copy it to another NV12 texture - when necessary. + when necessary. This enum is deprecated. See crbug.com/1401462. </int> <int value="3" label="BIND"> Bind the NV12 decoder texture directly to the texture used in ANGLE.
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml index 95adb14..dd99621 100644 --- a/tools/metrics/histograms/metadata/arc/histograms.xml +++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -114,6 +114,13 @@ <variant name=".Roblox" summary="Online game: Roblox"/> </variants> +<variants name="ArcSyncAppTypes"> + <variant name="Expected" summary="Apps expected to be synced"/> + <variant name="Installed" summary="Apps installed"/> + <variant name="NotInstalled" + summary="Apps that were expected but not installed"/> +</variants> + <variants name="ArcUserTypes"> <variant name=".ActiveDirectory" summary="User with active directory account"/> @@ -532,6 +539,31 @@ </summary> </histogram> +<histogram name="Arc.AppSync.InitialSession.Latency" units="seconds" + expires_after="2023-06-20"> + <owner>batoon@google.com</owner> + <owner>arc-core@google.com</owner> + <summary> + Records the time from the start of app sync until the last finished + installation before the session ended. This is not the latency for total app + sync, since total app sync may occur over multiple sessions. Metrics are + emitted when a user logs off IFF it is the first session after opting in + during the sync consent screen. + </summary> +</histogram> + +<histogram name="Arc.AppSync.InitialSession.NumApps{ArcSyncAppTypes}" + units="apps" expires_after="2023-06-20"> + <owner>batoon@google.com</owner> + <owner>arc-core@google.com</owner> + <summary> + Records the count of {ArcSyncAppTypes} apps during the initial session for + app sync. Metrics are emitted when a user logs off IFF it is the first + session after opting in during the sync consent screen. + </summary> + <token key="ArcSyncAppTypes" variants="ArcSyncAppTypes"/> +</histogram> + <histogram name="Arc.AppUninstallReason" enum="UninstallCounterReasonEnum" expires_after="2023-06-04"> <owner>thanhdng@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index e529bb9..c5103e3 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -3703,6 +3703,21 @@ </summary> </histogram> +<histogram name="Ash.Personalization.Ambient.GooglePhotosPreviewsLoadTime" + units="ms" expires_after="2023-12-01"> + <owner>cowmoo@google.com</owner> + <owner>assistive-eng@google.com</owner> + <summary> + Emitted when a request to load ambient mode google photos albums preview + images completes, but only upon first page load. This roughly corresponds to + user perceived time it takes to load the ambient preview section of + Personalization App. Does not emit if a user opens Personalization App onto + a page that does not load google photos albums previews. Does not emit + unless the user already has ambient mode enabled and Google Photos selected + as the source upon first opening Personalization App. + </summary> +</histogram> + <histogram name="Ash.Personalization.AmbientMode.AnimationTheme" enum="AmbientModeAnimationTheme" expires_after="2023-06-18"> <owner>jasontt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index fa5dfb3..f08a5a84 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -3141,6 +3141,36 @@ </summary> </histogram> +<histogram + name="Extensions.WebRequest.BeforeRequestDeclarativeNetRequestEvaluationTime" + units="ms" expires_after="2023-12-01"> + <owner>rdevlin.cronin@chromium.org</owner> + <owner>src/extensions/OWNERS</owner> + <summary> + The total amount of time taken to evaluate declarativeNetRequest rules in + the onBeforeRequest stage, measured in milliseconds. Recorded once per + request if and only if at least one declarativeNetRequest rule is present. + </summary> +</histogram> + +<histogram + name="Extensions.WebRequest.BeforeRequestListenerEvaluationTime.{HandlerTypes}" + units="ms" expires_after="2023-12-01"> + <owner>rdevlin.cronin@chromium.org</owner> + <owner>src/extensions/OWNERS</owner> + <summary> + The total amount of time, measured in milliseconds, between when an event is + dispatched to webRequest listeners and when all responses are received and + handled for an onBeforeRequest event. Emitted when there are {HandlerTypes} + for the request. Recorded once per request if the request completes. + </summary> + <token key="HandlerTypes"> + <variant name="WebRequestAndDeclarativeNetRequest" + summary="both webRequest listeners and declarativeNetRequest rules"/> + <variant name="WebRequestOnly" summary="only webRequest listeners"/> + </token> +</histogram> + <histogram name="Extensions.WebRequest.EventListenerFlag" enum="WebRequestEventListenerFlag" expires_after="never"> <!-- expires-never: For monitoring Web Request API usage statistics. -->
diff --git a/tools/metrics/histograms/metadata/fastpair/histograms.xml b/tools/metrics/histograms/metadata/fastpair/histograms.xml index d9854a6..c1bf962 100644 --- a/tools/metrics/histograms/metadata/fastpair/histograms.xml +++ b/tools/metrics/histograms/metadata/fastpair/histograms.xml
@@ -34,6 +34,30 @@ </summary> </histogram> +<histogram name="FastPair.Handshake.AttemptCount" units="count" + expires_after="2023-06-01"> + <owner>akingsb@google.com</owner> + <owner>jackshira@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the number of attempts needed to successfully create a handshake. + Currently the highest allowed attempt number is 3. Emitted following a + successful handshake. No metric is emitted on failure. + </summary> +</histogram> + +<histogram name="FastPair.Handshake.EffectiveSuccessRate" enum="BooleanSuccess" + expires_after="2023-06-01"> + <owner>akingsb@google.com</owner> + <owner>jackshira@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records the effective success rate of creating a handshake during the Fast + Pair pairing protocol. Emitted following the attempted creation of the + handshake and all retries. + </summary> +</histogram> + <histogram name="FastPair.InitialPairing" enum="FastPairInitialSuccessFunnelEvent" expires_after="2023-06-01"> <owner>jackshira@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/oobe/histograms.xml b/tools/metrics/histograms/metadata/oobe/histograms.xml index 7819143..563ce4d 100644 --- a/tools/metrics/histograms/metadata/oobe/histograms.xml +++ b/tools/metrics/histograms/metadata/oobe/histograms.xml
@@ -616,6 +616,18 @@ <token key="OOBEScreenName_ExitReason" variants="OOBEScreenName_ExitReason"/> </histogram> +<histogram name="OOBE.StepShownStatus.Multidevice-setup-screen.Skipped" + enum="OobeMultideviceScreenSkippedReason" expires_after="2023-11-01"> + <owner>bhartmire@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + The reason why the Multidevice setup screen is skipped in OOBE. Recorded + when determining that the screen should be skipped. This metric breaks down + the "Not shown" bucket of + "OOBE.StepShownStatus.Multidevice-setup-screen". + </summary> +</histogram> + <histogram name="OOBE.StepShownStatus.{OOBELegacyScreenName}" enum="BooleanShown" expires_after="never"> <!-- expires-never: Core metric for monitoring OOBE flow regressions. -->
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 131d14429..b275854 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -513,6 +513,9 @@ </event> <event name="AdPageLoadCustomSampling2" singular="True"> + <obsolete> + Removed 2022/12 in favor of AdPageLoadCustomSampling3 + </obsolete> <owner>yaoxia@chromium.org</owner> <owner>johnidel@chromium.org</owner> <owner>jkarlin@chromium.org</owner> @@ -563,6 +566,58 @@ </metric> </event> +<event name="AdPageLoadCustomSampling3" singular="True"> + <owner>yaoxia@chromium.org</owner> + <owner>johnidel@chromium.org</owner> + <owner>jkarlin@chromium.org</owner> + <summary> + Recorded when the page is being destroyed/navigated away or when the app + enters the background on mobile. This is separate from the `AdPageLoad` + event to allow it to be recorded on all pages (i.e. not only pages that have + loaded non-zero ad byte), and to allow a potentially different sampling. + Both iframe and img ads are covered. + </summary> + <metric name="AverageViewportAdDensity"> + <summary> + The estimated average viewport ad density. Each density value is + calculated as the area of (iframe and img) ads within the viewport * 100 / + viewport area, where each overlapping area is counted once. And this + returns the average of the densities accumulated over the page load time + rounded to the nearest integer. + </summary> + </metric> + <metric name="KurtosisViewportAdDensity"> + <summary> + The estimated kurtosis of the viewport ad density. Each density value is + calculated as the area of (iframe and img) ads within the viewport * 100 / + viewport area, where each overlapping area is counted once. And this + returns the kurtosis of the densities accumulated over the page load time + rounded to the nearest exponential bucket integer with bucket spacing 1.3. + For negative values, the bucketing will be taken on its magnitude part. + </summary> + </metric> + <metric name="SkewnessViewportAdDensity"> + <summary> + The estimated skewness of the viewport ad density. Each density value is + calculated as the area of (iframe and img) ads within the viewport * 100 / + viewport area, where each overlapping area is counted once. And this + returns the skewness of the densities accumulated over the page load time + rounded to the nearest exponential bucket integer with bucket spacing 1.3. + For negative values, the bucketing will be taken on its magnitude part. + </summary> + </metric> + <metric name="VarianceViewportAdDensity"> + <summary> + The estimated variance of the viewport ad density. Each density value is + calculated as the area of (iframe and img) ads within the viewport * 100 / + viewport area, where each overlapping area is counted once. And this + returns the variance of the densities accumulated over the page load time + rounded to the nearest exponential bucket integer with bucket spacing 1.3. + For negative values, the bucketing will be taken on its magnitude part. + </summary> + </metric> +</event> + <event name="AdsIntervention.LastIntervention" singular="True"> <owner>yaoxia@google.com</owner> <owner>chrome-ads-core@google.com</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 396de62..82e24c29 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,15 +6,15 @@ }, "win": { "hash": "0befcfb83f92421c85513c0d86328dd1fbffd5ba", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/b177a9b77d364faf675687204c9e48b8fd4d813c/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/2e920f3a489071ad7c98f6c84eba83f259f107a2/trace_processor_shell.exe" }, "linux_arm": { "hash": "6373f26144aad58f230d11d6a91efda5a09c9873", "full_remote_path": "perfetto-luci-artifacts/v31.0/linux-arm/trace_processor_shell" }, "mac": { - "hash": "642e3e46788e22f52302b04aea6422f7810718e1", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/b177a9b77d364faf675687204c9e48b8fd4d813c/trace_processor_shell" + "hash": "9ea16498678b255c71f01a9228448e6b812c6c2f", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/2e920f3a489071ad7c98f6c84eba83f259f107a2/trace_processor_shell" }, "mac_arm64": { "hash": "5f47ee79e59d00bf3889d30ca52315522c158040", @@ -22,7 +22,7 @@ }, "linux": { "hash": "e84516277d57cf556b47707d89511acc85bd8aeb", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/b177a9b77d364faf675687204c9e48b8fd4d813c/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/2e920f3a489071ad7c98f6c84eba83f259f107a2/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 8a9ea10..fe1993b 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -2245,31 +2245,30 @@ node->id())); } else { // --- Begin temporary change --- - // TODO(crbug.com/1156601) Revert this once we have the crash data we - // need (crrev.com/c/2892259) - // Diagnose strange errors "Node 1 reparented from 0 to 2", which - // sounds like the root node is getting the <html> element as a parent - // -- in the normal case, the root is 1 and <html> is 2. + // TODO(crbug.com/1156601, crbug.com/1402673) Revert this once we have + // the crash data we need (crrev.com/c/2892259) Diagnose strange + // errors: + // Node did not have a previous parent, but reparenting error + // triggered: + // * New parent = id=3 rootWebArea FOCUSABLE + // * Child = id=1 rootWebArea (0, 0)-(0, 0) busy=true std::ostringstream error; error << "Node did not have a previous parent, but " "reparenting error triggered:" - << "\n* Child = " << *child << "\n* New parent = " << *node << "\n* root_will_be_created = " << update_state->root_will_be_created << "\n* pending_root_id = " << (update_state->pending_root_id ? *update_state->pending_root_id : kInvalidAXNodeID) - << "\nTree update: " - << update_state->pending_tree_update->ToString( - /*verbose*/ false); - - // Add a crash key so we can figure out why this is happening. - static crash_reporter::CrashKeyString<256> ax_tree_error( - "ax_reparenting_error"); - ax_tree_error.Set(error.str()); - LOG(ERROR) << error.str(); - CHECK(false); + << "\n* new parent = " << *node << "\n* Old parent = " + << (child->parent() + ? child->parent()->data().ToString(/*verbose*/ false) + : "-") + << "\n* child = " << *child; + // Crash with crash keys for debugging. + RecordError(*update_state, error.str()); + CHECK(false) << error.str(); // --- End temporary change --- } success = false;
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h index d16eca17..b8324f1 100644 --- a/ui/accessibility/ax_tree_serializer.h +++ b/ui/accessibility/ax_tree_serializer.h
@@ -614,6 +614,8 @@ client_id_map_[client_node->id] = client_node; } + DCHECK_EQ(tree_->GetId(tree_->GetRoot()), client_root_->id); + // We're about to serialize it, so mark it as valid. client_node->invalid = false; client_node->ignored = tree_->IsIgnored(node); @@ -716,8 +718,25 @@ AXNodeData* serialized_node = &out_update->nodes[serialized_node_index]; tree_->SerializeNode(node, serialized_node); - if (serialized_node->id == client_root_->id) + if (serialized_node->id == client_root_->id) { out_update->root_id = serialized_node->id; + CHECK(!client_root_->parent) << "The root cannot have a parent:"; + // << "\n* Root: " + // << tree_->GetDebugString(tree_->GetFromId(out_update->root_id)) + // << "\n* Root's parent: " + // << tree_->GetDebugString(tree_->GetFromId(client_root_->parent->id)); + + } else { + DCHECK(serialized_node->role != ax::mojom::Role::kRootWebArea) + << "A kRootWebArea role was used on an object that is not the root: " + << "\n* Actual root: " << tree_->GetDebugString(tree_->GetRoot()) + << "\n* Illegal node with root web area role: " + << tree_->GetDebugString(tree_->GetFromId(serialized_node->id)) + << "\n* Parent of illegal node: " + << (client_node->parent ? tree_->GetDebugString(tree_->GetFromId( + client_node->parent->id)) + : ""); + } } // Iterate over the children, serialize them, and update the ClientTreeNode
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 8f6206c..69585cd 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -157,10 +157,6 @@ "java/res/drawable-mdpi/ic_expand_less_black_24dp.png", "java/res/drawable-mdpi/ic_expand_more_black_24dp.png", "java/res/drawable-mdpi/popup_bg.9.png", - "java/res/drawable-v21/transition_expand_less_expand_more_black_24dp.xml", - "java/res/drawable-v21/transition_expand_more_expand_less_black_24dp.xml", - "java/res/drawable-v23/dialog_bg_baseline.xml", - "java/res/drawable-v23/menu_bg_baseline.xml", "java/res/drawable-xhdpi/btn_close.png", "java/res/drawable-xhdpi/ic_expand_less_black_24dp.png", "java/res/drawable-xhdpi/ic_expand_more_black_24dp.png", @@ -174,11 +170,15 @@ "java/res/drawable-xxxhdpi/ic_expand_more_black_24dp.png", "java/res/drawable-xxxhdpi/popup_bg.9.png", "java/res/drawable/custom_toast_background.xml", + "java/res/drawable/dialog_bg_baseline.xml", "java/res/drawable/drag_handlebar.xml", "java/res/drawable/drag_shadow_background.xml", "java/res/drawable/ic_apps_blue_24dp.xml", "java/res/drawable/ic_expand_more_horizontal_black_24dp.xml", "java/res/drawable/ic_globe_24dp.xml", + "java/res/drawable/menu_bg_baseline.xml", + "java/res/drawable/transition_expand_less_expand_more_black_24dp.xml", + "java/res/drawable/transition_expand_more_expand_less_black_24dp.xml", "java/res/font/accent_font.xml", "java/res/layout/custom_toast_layout.xml", "java/res/layout/dropdown_item.xml", @@ -189,9 +189,7 @@ "java/res/values-night/dimens.xml", "java/res/values-sw600dp/dimens.xml", "java/res/values-sw600dp/values.xml", - "java/res/values-sw720dp-v17/values.xml", - "java/res/values-v17/styles.xml", - "java/res/values-v21/styles.xml", + "java/res/values-sw720dp/values.xml", "java/res/values-v31/colors.xml", "java/res/values/attrs.xml", "java/res/values/color_palette.xml",
diff --git a/ui/android/java/res/drawable-v23/dialog_bg_baseline.xml b/ui/android/java/res/drawable/dialog_bg_baseline.xml similarity index 100% rename from ui/android/java/res/drawable-v23/dialog_bg_baseline.xml rename to ui/android/java/res/drawable/dialog_bg_baseline.xml
diff --git a/ui/android/java/res/drawable-v23/menu_bg_baseline.xml b/ui/android/java/res/drawable/menu_bg_baseline.xml similarity index 100% rename from ui/android/java/res/drawable-v23/menu_bg_baseline.xml rename to ui/android/java/res/drawable/menu_bg_baseline.xml
diff --git a/ui/android/java/res/drawable-v21/transition_expand_less_expand_more_black_24dp.xml b/ui/android/java/res/drawable/transition_expand_less_expand_more_black_24dp.xml similarity index 100% rename from ui/android/java/res/drawable-v21/transition_expand_less_expand_more_black_24dp.xml rename to ui/android/java/res/drawable/transition_expand_less_expand_more_black_24dp.xml
diff --git a/ui/android/java/res/drawable-v21/transition_expand_more_expand_less_black_24dp.xml b/ui/android/java/res/drawable/transition_expand_more_expand_less_black_24dp.xml similarity index 100% rename from ui/android/java/res/drawable-v21/transition_expand_more_expand_less_black_24dp.xml rename to ui/android/java/res/drawable/transition_expand_more_expand_less_black_24dp.xml
diff --git a/ui/android/java/res/values-sw720dp-v17/values.xml b/ui/android/java/res/values-sw720dp/values.xml similarity index 100% rename from ui/android/java/res/values-sw720dp-v17/values.xml rename to ui/android/java/res/values-sw720dp/values.xml
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml deleted file mode 100644 index b4f57c3..0000000 --- a/ui/android/java/res/values-v17/styles.xml +++ /dev/null
@@ -1,327 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2013 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<resources xmlns:tools="http://schemas.android.com/tools"> - <style name="DropdownPopupWindow" parent="@android:style/Widget.ListPopupWindow"> - <item name="android:popupBackground">@drawable/dialog_bg_baseline</item> - </style> - - <!-- Buttons --> - <style name="FilledButtonThemeOverlay"> - <item name="android:buttonStyle">@style/FilledButton</item> - </style> - <style name="FilledButtonThemeOverlay.Flat" tools:ignore="UnusedResources"> - <item name="android:buttonStyle">@style/FilledButton.Flat</item> - </style> - <style name="TextButtonThemeOverlay" tools:ignore="UnusedResources"> - <item name="android:buttonStyle">@style/TextButton</item> - </style> - - <style name="ButtonCompatBase"> - <item name="android:minWidth">@dimen/button_min_width</item> - <item name="android:minHeight">@dimen/min_touch_target_size</item> - <item name="android:paddingStart">20dp</item> - <item name="android:paddingEnd">20dp</item> - <item name="android:paddingTop">5dp</item> - <item name="android:paddingBottom">5dp</item> - <item name="android:focusable">true</item> - <item name="android:clickable">true</item> - <item name="android:gravity">center_vertical|center_horizontal</item> - <item name="verticalInset">@dimen/button_bg_vertical_inset</item> - </style> - <style name="FilledButton" parent="ButtonCompatBase" tools:ignore="UnusedResources"> - <item name="android:paddingStart">24dp</item> - <item name="android:paddingEnd">24dp</item> - <item name="android:textAppearance">@style/TextAppearance.Button.Text.Filled</item> - <item name="buttonTextColor">?attr/globalFilledButtonTextColor</item> - <item name="buttonColor">?attr/globalFilledButtonBgColor</item> - <item name="rippleColor">@color/filled_button_ripple_color</item> - <item name="buttonRaised">true</item> - </style> - <style name="FilledButton.Flat" tools:ignore="UnusedResources"> - <item name="buttonRaised">false</item> - </style> - <style name="TextButton" parent="ButtonCompatBase" tools:ignore="UnusedResources"> - <item name="android:paddingStart">8dp</item> - <item name="android:paddingEnd">8dp</item> - <item name="android:textAppearance">@style/TextAppearance.Button.Text.Blue</item> - <item name="buttonTextColor">?attr/globalTextButtonTextColor</item> - <item name="buttonColor">@android:color/transparent</item> - <!-- - If ?attr/globalTextButtonRippleColor isn't defined in the theme, ButtonCompat will fall - back to a blue ripple color for buttons with transparent background and a white one for - the buttons with a solid background. - --> - <item name="rippleColor">?attr/globalTextButtonRippleColor</item> - <item name="buttonRaised">false</item> - </style> - <style name="OutlinedButton" parent="TextButton" tools:ignore="UnusedResources"> - <item name="borderWidth">@dimen/button_outlined_border_width</item> - <item name="borderColor">?attr/globalOutlinedButtonBorderColor</item> - </style> - - <!-- Used by Chrome and Content --> - <style name="TextAppearance" parent="android:TextAppearance" tools:ignore="UnusedResources" /> - <style name="TextAppearance.RobotoMediumStyle"> - <item name="android:fontFamily">sans-serif</item> - <item name="android:textStyle">bold</item> - </style> - <!-- This style is overridden downstream to set accent_font_medium as the font family. --> - <style name="TextAppearance.AccentMediumStyle" parent="TextAppearance.RobotoMediumStyle" /> - - <!-- Base Text Styles --> - <!-- - Define incomplete base text styles. The styles in this section are used - to create other text styles below and should not be used directly to style - text as they are missing textColor attributes - --> - <style name="TextAppearance.Headline"> - <item name="android:fontFamily">@font/accent_font</item> - <item name="android:textSize">@dimen/headline_size</item> - </style> - <style name="TextAppearance.HeadlineThick" parent="TextAppearance.AccentMediumStyle"> - <item name="android:textSize">@dimen/headline_size</item> - </style> - <style name="TextAppearance.TextLarge"> - <item name="android:textSize">@dimen/text_size_large</item> - </style> - <style name="TextAppearance.TextMediumThick" parent="TextAppearance.RobotoMediumStyle"> - <item name="android:textSize">@dimen/text_size_medium</item> - </style> - <style name="TextAppearance.TextAccentMediumThick" parent="TextAppearance.AccentMediumStyle"> - <item name="android:textSize">@dimen/text_size_medium</item> - </style> - - <style name="TextAppearance.TextMedium"> - <item name="android:textSize">@dimen/text_size_medium</item> - </style> - - <style name="TextAppearance.TextSmall"> - <item name="android:textSize">@dimen/text_size_small</item> - </style> - - <!-- Non Adaptive Text Styles --> - <!-- Light version --> - <style name="TextAppearance.Headline.Primary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> - </style> - <style name="TextAppearance.HeadlineThick.Primary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> - </style> - <style name="TextAppearance.TextLarge.Primary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> - </style> - <style name="TextAppearance.TextMediumThick.Primary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> - </style> - <style name="TextAppearance.TextMedium.Primary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> - </style> - <style name="TextAppearance.TextSmall.Primary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_light_list</item> - </style> - <style name="TextAppearance.TextMediumThick.Secondary.Baseline.Light" - parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_light_list</item> - </style> - - <style name="TextAppearance.TextLarge.Secondary.Baseline.Light" - parent="TextAppearance.TextLarge" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_light_list</item> - </style> - <style name="TextAppearance.TextMedium.Secondary.Baseline.Light" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_light_list</item> - </style> - - <style name="TextAppearance.TextLarge.Disabled.Baseline.Light" parent="TextAppearance.TextLarge" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_disabled_light</item> - </style> - <style name="TextAppearance.TextSmall.Disabled.Baseline.Light" parent="TextAppearance.TextSmall" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_disabled_light</item> - </style> - - <style name="TextAppearance.WhiteLink" tools:ignore="UnusedResources"> - <item name="android:textColor">@android:color/white</item> - <item name="android:textSize">@dimen/text_size_medium</item> - <item name="android:textStyle">bold</item> - </style> - - <style name="TextAppearance.TextSmallThick.Secondary.Baseline.Light" - parent="TextAppearance.TextSmall"> - <item name="android:textColor">@color/default_text_color_secondary_light_list</item> - <item name="android:textStyle">bold</item> - </style> - - <!-- Dark version --> - <style name="TextAppearance.Headline.Primary.Baseline.Dark" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_dark</item> - </style> - <style name="TextAppearance.TextLarge.Primary.Baseline.Dark" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_dark</item> - </style> - <style name="TextAppearance.TextMedium.Primary.Baseline.Dark" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_dark</item> - </style> - <style name="TextAppearance.TextSmall.Primary.Baseline.Dark" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_dark</item> - </style> - - <style name="TextAppearance.TextLarge.Secondary.Baseline.Dark" - parent="TextAppearance.TextLarge" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_dark</item> - </style> - <style name="TextAppearance.TextMedium.Secondary.Baseline.Dark" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_dark</item> - </style> - <style name="TextAppearance.TextSmall.Secondary.Baseline.Dark" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_dark</item> - </style> - <style name="TextAppearance.TextMediumThick.Secondary.Baseline.Dark" - parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_secondary_dark</item> - </style> - - <style name="TextAppearance.TextLarge.Disabled.Baseline.Dark" parent="TextAppearance.TextLarge" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_disabled_dark</item> - </style> - <style name="TextAppearance.TextMedium.Disabled.Baseline.Dark" parent="TextAppearance.TextMedium" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_disabled_dark</item> - </style> - <style name="TextAppearance.TextSmall.Disabled.Baseline.Dark" parent="TextAppearance.TextSmall" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_disabled_dark</item> - </style> - - <!-- Blue And Button Text Styles --> - <style name="TextAppearance.TextMediumThick.Green"> - <item name="android:textColor">@color/default_green</item> - </style> - <style name="TextAppearance.TextMediumThick.Green.Dark"> - <item name="android:textColor">@color/default_green_dark</item> - </style> - - <style name="TextAppearance.Button.Text.Blue" parent="TextAppearance.TextAccentMediumThick" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/blue_when_enabled_list</item> - </style> - <style name="TextAppearance.Button.Text.Blue.Dark" parent="TextAppearance.TextAccentMediumThick" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/blue_when_enabled_dark</item> - </style> - <style name="TextAppearance.Button.Text.Filled" parent="TextAppearance.TextAccentMediumThick"> - <item name="android:textColor">@color/default_text_color_on_accent1_baseline_list</item> - </style> - <style name="TextAppearance.Button.Text.Inverse" parent="TextAppearance.TextAccentMediumThick" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_on_accent1_baseline_list</item> - </style> - <style name="TextAppearance.MenuChip.Text.Blue" parent="TextAppearance.Button.Text.Blue"> - <item name="android:textSize">@dimen/text_size_small</item> - </style> - - <!-- Blue Non Adaptive button text styles --> - <style name="TextAppearance.Button.Text.Filled.Baseline.Dark" parent="TextAppearance.TextAccentMediumThick"> - <item name="android:textColor">@color/default_text_color_on_accent1_dark</item> - </style> - - <!-- Blue Non Adaptive Text Styles --> - <style name="TextAppearance.TextMedium.Blue.Baseline.Light" parent="TextAppearance.TextMedium"> - <item name="android:textColor">@color/default_icon_color_blue_light</item> - </style> - <style name="TextAppearance.TextMediumThick.Blue.Baseline.Light" - parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_icon_color_blue_light</item> - </style> - <style name="TextAppearance.TextLarge.Blue.Baseline.Dark" parent="TextAppearance.TextLarge" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_icon_color_blue_dark</item> - </style> - <style name="TextAppearance.TextMedium.Blue.Baseline.Dark" parent="TextAppearance.TextMedium" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_icon_color_blue_dark</item> - </style> - <style name="TextAppearance.TextSmall.Blue.Baseline.Dark" parent="TextAppearance.TextSmall" - tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_icon_color_blue_dark</item> - </style> - <style name="TextAppearance.TextMediumThick.Blue.Baseline.Dark" - parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_icon_color_blue_dark</item> - </style> - - <!-- Baseline or non-dynamic text styles --> - - <!-- Primary text styles --> - <style name="TextAppearance.Headline.Primary.Baseline" parent="TextAppearance.Headline"> - <item name="android:textColor">@color/default_text_color_list_baseline</item> - </style> - <style name="TextAppearance.HeadlineThick.Primary.Baseline" parent="TextAppearance.HeadlineThick"> - <item name="android:textColor">@color/default_text_color_list_baseline</item> - </style> - - <style name="TextAppearance.TextLarge.Primary.Baseline" parent="TextAppearance.TextLarge"> - <item name="android:textColor">@color/default_text_color_list_baseline</item> - </style> - - <style name="TextAppearance.TextMediumThick.Primary.Baseline" parent="TextAppearance.TextMediumThick"> - <item name="android:textColor">@color/default_text_color_list_baseline</item> - </style> - - <style name="TextAppearance.TextMedium.Primary.Baseline" parent="TextAppearance.TextMedium"> - <item name="android:textColor">@color/default_text_color_list_baseline</item> - </style> - - <style name="TextAppearance.TextSmall.Primary.Baseline" parent="TextAppearance.TextSmall"> - <item name="android:textColor">@color/default_text_color_list_baseline</item> - </style> - - <!-- Secondary text styles --> - <style name="TextAppearance.TextMedium.Secondary.Baseline" parent="TextAppearance.TextMedium"> - <item name="android:textColor">@color/default_text_color_secondary_list_baseline</item> - </style> - - <style name="TextAppearance.TextSmall.Secondary.Baseline" parent="TextAppearance.TextSmall"> - <item name="android:textColor">@color/default_text_color_secondary_list_baseline</item> - </style> - - <!-- Error Text Styles --> - <style name="TextAppearance.ErrorCaption" tools:ignore="UnusedResources"> - <item name="android:textColor">@color/default_text_color_error</item> - <item name="android:textSize">@dimen/text_size_small</item> - </style> - - <!-- Toast UI --> - <style name="TextAppearance.Toast" parent="TextAppearance.TextSmall"> - <item name="android:textColor">@color/default_text_color_light</item> - </style> - - <!-- Dividers --> - <style name="HorizontalDivider" - tools:ignore="UnusedResources"> - <item name="android:layout_width">match_parent</item> - <item name="android:layout_height">@dimen/divider_height</item> - <item name="android:background">?android:attr/listDivider</item> - <item name="android:importantForAccessibility">no</item> - </style> - <style name="VerticalDivider" - tools:ignore="UnusedResources"> - <item name="android:layout_width">@dimen/divider_height</item> - <item name="android:layout_height">match_parent</item> - <item name="android:background">?android:attr/listDivider</item> - <item name="android:importantForAccessibility">no</item> - </style> - - <style name="ThemeOverlay.UI.SelectionHandle" parent=""> - <item name="colorControlActivated">@color/default_control_color_active_baseline</item> - </style> - -</resources>
diff --git a/ui/android/java/res/values-v21/styles.xml b/ui/android/java/res/values-v21/styles.xml deleted file mode 100644 index 94f4f41..0000000 --- a/ui/android/java/res/values-v21/styles.xml +++ /dev/null
@@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2015 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Used by Chrome and Content --> - <style name="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> - <item name="android:fontFamily">sans-serif-medium</item> - </style> -</resources>
diff --git a/ui/android/java/res/values/styles.xml b/ui/android/java/res/values/styles.xml index 37042d7..fea730ee 100644 --- a/ui/android/java/res/values/styles.xml +++ b/ui/android/java/res/values/styles.xml
@@ -1,11 +1,329 @@ <?xml version="1.0" encoding="utf-8"?> + <!-- -Copyright 2022 The Chromium Authors +Copyright 2013 The Chromium Authors Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> + <style name="DropdownPopupWindow" parent="@android:style/Widget.ListPopupWindow"> + <item name="android:popupBackground">@drawable/dialog_bg_baseline</item> + </style> + + <!-- Buttons --> + <style name="FilledButtonThemeOverlay"> + <item name="android:buttonStyle">@style/FilledButton</item> + </style> + <style name="FilledButtonThemeOverlay.Flat" tools:ignore="UnusedResources"> + <item name="android:buttonStyle">@style/FilledButton.Flat</item> + </style> + <style name="TextButtonThemeOverlay" tools:ignore="UnusedResources"> + <item name="android:buttonStyle">@style/TextButton</item> + </style> + + <style name="ButtonCompatBase"> + <item name="android:minWidth">@dimen/button_min_width</item> + <item name="android:minHeight">@dimen/min_touch_target_size</item> + <item name="android:paddingStart">20dp</item> + <item name="android:paddingEnd">20dp</item> + <item name="android:paddingTop">5dp</item> + <item name="android:paddingBottom">5dp</item> + <item name="android:focusable">true</item> + <item name="android:clickable">true</item> + <item name="android:gravity">center_vertical|center_horizontal</item> + <item name="verticalInset">@dimen/button_bg_vertical_inset</item> + </style> + <style name="FilledButton" parent="ButtonCompatBase" tools:ignore="UnusedResources"> + <item name="android:paddingStart">24dp</item> + <item name="android:paddingEnd">24dp</item> + <item name="android:textAppearance">@style/TextAppearance.Button.Text.Filled</item> + <item name="buttonTextColor">?attr/globalFilledButtonTextColor</item> + <item name="buttonColor">?attr/globalFilledButtonBgColor</item> + <item name="rippleColor">@color/filled_button_ripple_color</item> + <item name="buttonRaised">true</item> + </style> + <style name="FilledButton.Flat" tools:ignore="UnusedResources"> + <item name="buttonRaised">false</item> + </style> + <style name="TextButton" parent="ButtonCompatBase" tools:ignore="UnusedResources"> + <item name="android:paddingStart">8dp</item> + <item name="android:paddingEnd">8dp</item> + <item name="android:textAppearance">@style/TextAppearance.Button.Text.Blue</item> + <item name="buttonTextColor">?attr/globalTextButtonTextColor</item> + <item name="buttonColor">@android:color/transparent</item> + <!-- + If ?attr/globalTextButtonRippleColor isn't defined in the theme, ButtonCompat will fall + back to a blue ripple color for buttons with transparent background and a white one for + the buttons with a solid background. + --> + <item name="rippleColor">?attr/globalTextButtonRippleColor</item> + <item name="buttonRaised">false</item> + </style> + <style name="OutlinedButton" parent="TextButton" tools:ignore="UnusedResources"> + <item name="borderWidth">@dimen/button_outlined_border_width</item> + <item name="borderColor">?attr/globalOutlinedButtonBorderColor</item> + </style> + + <!-- Used by Chrome and Content --> + <style name="TextAppearance" parent="android:TextAppearance" tools:ignore="UnusedResources" /> + <!-- Used by Chrome and Content --> + <style name="TextAppearance.RobotoMediumStyle" tools:ignore="UnusedResources"> + <item name="android:fontFamily">sans-serif-medium</item> + </style> + <!-- This style is overridden downstream to set accent_font_medium as the font family. --> + <style name="TextAppearance.AccentMediumStyle" parent="TextAppearance.RobotoMediumStyle" /> + + <!-- Base Text Styles --> + <!-- + Define incomplete base text styles. The styles in this section are used + to create other text styles below and should not be used directly to style + text as they are missing textColor attributes + --> + <style name="TextAppearance.Headline"> + <item name="android:fontFamily">@font/accent_font</item> + <item name="android:textSize">@dimen/headline_size</item> + </style> + <style name="TextAppearance.HeadlineThick" parent="TextAppearance.AccentMediumStyle"> + <item name="android:textSize">@dimen/headline_size</item> + </style> + <style name="TextAppearance.TextLarge"> + <item name="android:textSize">@dimen/text_size_large</item> + </style> + <style name="TextAppearance.TextMediumThick" parent="TextAppearance.RobotoMediumStyle"> + <item name="android:textSize">@dimen/text_size_medium</item> + </style> + <style name="TextAppearance.TextAccentMediumThick" parent="TextAppearance.AccentMediumStyle"> + <item name="android:textSize">@dimen/text_size_medium</item> + </style> + + <style name="TextAppearance.TextMedium"> + <item name="android:textSize">@dimen/text_size_medium</item> + </style> + + <style name="TextAppearance.TextSmall"> + <item name="android:textSize">@dimen/text_size_small</item> + </style> + + <!-- Non Adaptive Text Styles --> + <!-- Light version --> + <style name="TextAppearance.Headline.Primary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_light_list</item> + </style> + <style name="TextAppearance.HeadlineThick.Primary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_light_list</item> + </style> + <style name="TextAppearance.TextLarge.Primary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_light_list</item> + </style> + <style name="TextAppearance.TextMediumThick.Primary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_light_list</item> + </style> + <style name="TextAppearance.TextMedium.Primary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_light_list</item> + </style> + <style name="TextAppearance.TextSmall.Primary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_light_list</item> + </style> + <style name="TextAppearance.TextMediumThick.Secondary.Baseline.Light" + parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_light_list</item> + </style> + + <style name="TextAppearance.TextLarge.Secondary.Baseline.Light" + parent="TextAppearance.TextLarge" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_light_list</item> + </style> + <style name="TextAppearance.TextMedium.Secondary.Baseline.Light" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_light_list</item> + </style> + + <style name="TextAppearance.TextLarge.Disabled.Baseline.Light" parent="TextAppearance.TextLarge" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_disabled_light</item> + </style> + <style name="TextAppearance.TextSmall.Disabled.Baseline.Light" parent="TextAppearance.TextSmall" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_disabled_light</item> + </style> + + <style name="TextAppearance.WhiteLink" tools:ignore="UnusedResources"> + <item name="android:textColor">@android:color/white</item> + <item name="android:textSize">@dimen/text_size_medium</item> + <item name="android:textStyle">bold</item> + </style> + + <style name="TextAppearance.TextSmallThick.Secondary.Baseline.Light" + parent="TextAppearance.TextSmall"> + <item name="android:textColor">@color/default_text_color_secondary_light_list</item> + <item name="android:textStyle">bold</item> + </style> + + <!-- Dark version --> + <style name="TextAppearance.Headline.Primary.Baseline.Dark" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_dark</item> + </style> + <style name="TextAppearance.TextLarge.Primary.Baseline.Dark" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_dark</item> + </style> + <style name="TextAppearance.TextMedium.Primary.Baseline.Dark" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_dark</item> + </style> + <style name="TextAppearance.TextSmall.Primary.Baseline.Dark" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_dark</item> + </style> + + <style name="TextAppearance.TextLarge.Secondary.Baseline.Dark" + parent="TextAppearance.TextLarge" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_dark</item> + </style> + <style name="TextAppearance.TextMedium.Secondary.Baseline.Dark" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_dark</item> + </style> + <style name="TextAppearance.TextSmall.Secondary.Baseline.Dark" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_dark</item> + </style> + <style name="TextAppearance.TextMediumThick.Secondary.Baseline.Dark" + parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_secondary_dark</item> + </style> + + <style name="TextAppearance.TextLarge.Disabled.Baseline.Dark" parent="TextAppearance.TextLarge" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_disabled_dark</item> + </style> + <style name="TextAppearance.TextMedium.Disabled.Baseline.Dark" parent="TextAppearance.TextMedium" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_disabled_dark</item> + </style> + <style name="TextAppearance.TextSmall.Disabled.Baseline.Dark" parent="TextAppearance.TextSmall" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_disabled_dark</item> + </style> + + <!-- Blue And Button Text Styles --> + <style name="TextAppearance.TextMediumThick.Green"> + <item name="android:textColor">@color/default_green</item> + </style> + <style name="TextAppearance.TextMediumThick.Green.Dark"> + <item name="android:textColor">@color/default_green_dark</item> + </style> + + <style name="TextAppearance.Button.Text.Blue" parent="TextAppearance.TextAccentMediumThick" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/blue_when_enabled_list</item> + </style> + <style name="TextAppearance.Button.Text.Blue.Dark" parent="TextAppearance.TextAccentMediumThick" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/blue_when_enabled_dark</item> + </style> + <style name="TextAppearance.Button.Text.Filled" parent="TextAppearance.TextAccentMediumThick"> + <item name="android:textColor">@color/default_text_color_on_accent1_baseline_list</item> + </style> + <style name="TextAppearance.Button.Text.Inverse" parent="TextAppearance.TextAccentMediumThick" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_on_accent1_baseline_list</item> + </style> + <style name="TextAppearance.MenuChip.Text.Blue" parent="TextAppearance.Button.Text.Blue"> + <item name="android:textSize">@dimen/text_size_small</item> + </style> + + <!-- Blue Non Adaptive button text styles --> + <style name="TextAppearance.Button.Text.Filled.Baseline.Dark" parent="TextAppearance.TextAccentMediumThick"> + <item name="android:textColor">@color/default_text_color_on_accent1_dark</item> + </style> + + <!-- Blue Non Adaptive Text Styles --> + <style name="TextAppearance.TextMedium.Blue.Baseline.Light" parent="TextAppearance.TextMedium"> + <item name="android:textColor">@color/default_icon_color_blue_light</item> + </style> + <style name="TextAppearance.TextMediumThick.Blue.Baseline.Light" + parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_icon_color_blue_light</item> + </style> + <style name="TextAppearance.TextLarge.Blue.Baseline.Dark" parent="TextAppearance.TextLarge" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_icon_color_blue_dark</item> + </style> + <style name="TextAppearance.TextMedium.Blue.Baseline.Dark" parent="TextAppearance.TextMedium" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_icon_color_blue_dark</item> + </style> + <style name="TextAppearance.TextSmall.Blue.Baseline.Dark" parent="TextAppearance.TextSmall" + tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_icon_color_blue_dark</item> + </style> + <style name="TextAppearance.TextMediumThick.Blue.Baseline.Dark" + parent="TextAppearance.TextMediumThick" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_icon_color_blue_dark</item> + </style> + + <!-- Baseline or non-dynamic text styles --> + + <!-- Primary text styles --> + <style name="TextAppearance.Headline.Primary.Baseline" parent="TextAppearance.Headline"> + <item name="android:textColor">@color/default_text_color_list_baseline</item> + </style> + <style name="TextAppearance.HeadlineThick.Primary.Baseline" parent="TextAppearance.HeadlineThick"> + <item name="android:textColor">@color/default_text_color_list_baseline</item> + </style> + + <style name="TextAppearance.TextLarge.Primary.Baseline" parent="TextAppearance.TextLarge"> + <item name="android:textColor">@color/default_text_color_list_baseline</item> + </style> + + <style name="TextAppearance.TextMediumThick.Primary.Baseline" parent="TextAppearance.TextMediumThick"> + <item name="android:textColor">@color/default_text_color_list_baseline</item> + </style> + + <style name="TextAppearance.TextMedium.Primary.Baseline" parent="TextAppearance.TextMedium"> + <item name="android:textColor">@color/default_text_color_list_baseline</item> + </style> + + <style name="TextAppearance.TextSmall.Primary.Baseline" parent="TextAppearance.TextSmall"> + <item name="android:textColor">@color/default_text_color_list_baseline</item> + </style> + + <!-- Secondary text styles --> + <style name="TextAppearance.TextMedium.Secondary.Baseline" parent="TextAppearance.TextMedium"> + <item name="android:textColor">@color/default_text_color_secondary_list_baseline</item> + </style> + + <style name="TextAppearance.TextSmall.Secondary.Baseline" parent="TextAppearance.TextSmall"> + <item name="android:textColor">@color/default_text_color_secondary_list_baseline</item> + </style> + + <!-- Error Text Styles --> + <style name="TextAppearance.ErrorCaption" tools:ignore="UnusedResources"> + <item name="android:textColor">@color/default_text_color_error</item> + <item name="android:textSize">@dimen/text_size_small</item> + </style> + + <!-- Toast UI --> + <style name="TextAppearance.Toast" parent="TextAppearance.TextSmall"> + <item name="android:textColor">@color/default_text_color_light</item> + </style> + + <!-- Dividers --> + <style name="HorizontalDivider" + tools:ignore="UnusedResources"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">@dimen/divider_height</item> + <item name="android:background">?android:attr/listDivider</item> + <item name="android:importantForAccessibility">no</item> + </style> + <style name="VerticalDivider" + tools:ignore="UnusedResources"> + <item name="android:layout_width">@dimen/divider_height</item> + <item name="android:layout_height">match_parent</item> + <item name="android:background">?android:attr/listDivider</item> + <item name="android:importantForAccessibility">no</item> + </style> + + <style name="ThemeOverlay.UI.SelectionHandle" parent=""> + <item name="colorControlActivated">@color/default_control_color_active_baseline</item> + </style> + <!-- AnchoredPopupAnimationStyle --> <style name="AnchoredPopupAnimEndTop"> <item name="android:windowEnterAnimation">@anim/menu_enter</item>
diff --git a/ui/ozone/platform/flatland/ozone_platform_flatland.cc b/ui/ozone/platform/flatland/ozone_platform_flatland.cc index 37112a2..a5226787 100644 --- a/ui/ozone/platform/flatland/ozone_platform_flatland.cc +++ b/ui/ozone/platform/flatland/ozone_platform_flatland.cc
@@ -109,9 +109,6 @@ std::move(parent_token)); } - // TODO(fxbug.dev/93998): Add a hook for the RootPresenter equivalent of - // Flatland to ui::fuchsia::InitializeViewTokenAndPresentView() create a - // window. CHECK(properties.view_creation_token.value.is_valid()); return std::make_unique<FlatlandWindow>(window_manager_.get(), delegate, std::move(properties));
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index b3190c6b..5366707 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -350,7 +350,7 @@ (wl::get_version_of_object( connection_->zaura_shell()->wl_object()) >= ZAURA_SURFACE_SHOW_TOOLTIP_SINCE_VERSION) && - connection_->zaura_shell()->HasBugFix(1400226); + connection_->zaura_shell()->HasBugFix(1402158); } if (surface_factory_) {
diff --git a/ui/views/corewm/tooltip_aura.cc b/ui/views/corewm/tooltip_aura.cc index 971d26c..033cf28 100644 --- a/ui/views/corewm/tooltip_aura.cc +++ b/ui/views/corewm/tooltip_aura.cc
@@ -16,6 +16,7 @@ #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/screen_position_client.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -313,8 +314,13 @@ tooltip_window_ = window; auto new_tooltip_view = std::make_unique<TooltipView>(); - gfx::Point anchor_point = - position + window->GetBoundsInScreen().OffsetFromOrigin(); + + // Convert `position` to screen coordinates. + gfx::Point anchor_point = position; + aura::client::ScreenPositionClient* screen_position_client = + aura::client::GetScreenPositionClient(window->GetRootWindow()); + screen_position_client->ConvertPointToScreen(window, &anchor_point); + new_tooltip_view->SetMaxWidth(GetMaxWidth(anchor_point)); new_tooltip_view->SetText(tooltip_text); ui::OwnedWindowAnchor anchor;