diff --git a/DEPS b/DEPS index ff213fd..599934e 100644 --- a/DEPS +++ b/DEPS
@@ -306,15 +306,15 @@ # 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': '3a3475d12f220b795821eabae517ab7cb6f12c9f', + 'skia_revision': '9d220ebe40a0e8537f3e37d8ac1fbe4ac4dfa43a', # 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': 'b057218023961f8b94b0313dd6ddbcc274c06e74', + 'v8_revision': '13b0f9f24b88983f07952beb652e1bce97a4deb6', # 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': '35e49df77d01932715b8cd8dd3e1613cbd476561', + 'angle_revision': 'bdd3a778370b833bb91659971efa001c584900a8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -322,7 +322,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'cb1cd2f12898d7cdc0d9435be2244ce27f88afe3', + 'pdfium_revision': 'dda631d81103d0af8fa2fe4bd81e9da08435f989', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -377,11 +377,11 @@ # 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': 'b142d415308e1f3ace94f0f39807bf0198ee004f', + 'catapult_revision': 'd12e6887dd534569117c06f92e8c69c91e0ad12b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. - 'chromium_variations_revision': '510ec37c3f2bf8431f8c6f1a573d6826ed01d9e6', + 'chromium_variations_revision': '62652a482c1bc8658057a7fa7b216f638d0dfaae', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -397,7 +397,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': '7781523a3fc8f16c45a382676e73b1f7f28a58e5', + 'devtools_frontend_revision': 'c7e8227f786e657d8f82d6e9f1de859ed60280df', # 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. @@ -421,7 +421,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': '109e648f2f452424d2d1d0b1eba1e1b9fe036645', + 'dawn_revision': '3c117aa551537c3e7cc0f8cbb05d85fe76d466fc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -465,7 +465,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'cros_components_revision': 'b1b1b0b6ff08289f3f5d960947aa12db68775d41', + 'cros_components_revision': 'b7deff896ee3186e7d33a52ddde07da2400de2ad', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -500,7 +500,7 @@ 'libcxx_revision': '1f70899ab6d9d2c3c455fa7adb3f3cbd7bfdf215', # GN CIPD package version. - 'gn_version': 'git_revision:7367b0df0a0aa25440303998d54045bda73935a5', + 'gn_version': 'git_revision:85944ebc24a90ec1e489e85a46fdc68542c3146f', # ninja CIPD package version. # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja @@ -826,7 +826,7 @@ }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '8fa01e615655f80075f9149063032d3e3d5956df', + 'url': Var('chromium_git') + '/website.git' + '@' + '7e14119375ad198e276c3a2eecafb4f9b0970d1f', }, 'src/ios/third_party/earl_grey2/src': { @@ -1199,7 +1199,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'd4775b3834d55829a429cf165089e92261a9e426', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '14464a6787e9a358a6acdc532568e6fe3a347344', 'condition': 'checkout_src_internal', }, @@ -1846,10 +1846,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f4bf599a8b575df685c31d9c4729a70a04e377ed', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '7a6ef7301b5d84f751b483f9d5466b3696749c26', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '666950d6de30c9c26773208b0f861463b25ae37c', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '21edbe5d0dc7a506ff42b858969d16d0cbdd3a0b', + Var('webrtc_git') + '/src.git' + '@' + 'e6df126b798c0644010afeaddeb2e13053d8f192', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -4006,7 +4006,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'c8b84877296746df0c2ad8088c1e53d19b10c8bc', + 'b8fd6d1953501218760e0f7e2f0485c44d4925c1', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index b89421d1..e7ff79f 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2793,11 +2793,6 @@ "VirtualKeyboardRoundCorners", base::FEATURE_DISABLED_BY_DEFAULT); -// Enable or disable Nacl for virtual keyboard on ChromeOS. -BASE_FEATURE(kVirtualKeyboardRemoveNacl, - "VirtualKeyboardRemoveNacl", - base::FEATURE_DISABLED_BY_DEFAULT); - // Controls whether to allow enabling wake on WiFi features in shill. BASE_FEATURE(kWakeOnWifiAllowed, "WakeOnWifiAllowed",
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 53925f1..b45c7f1 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -558,8 +558,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEducationEnrollmentOobeFlow); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kMicMuteNotifications); -COMPONENT_EXPORT(ASH_CONSTANTS) -BASE_DECLARE_FEATURE(kMigrateOwnerKeyToPrivateSlot); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kMinimumChromeVersion); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kMojoDBusRelay); COMPONENT_EXPORT(ASH_CONSTANTS) @@ -793,8 +791,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSmdsSupport); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSnapGroup); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSnoopingProtection); -COMPONENT_EXPORT(ASH_CONSTANTS) -BASE_DECLARE_FEATURE(kStoreOwnerKeyInPrivateSlot); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kStylusBatteryStatus); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kStartAssistantAudioDecoderOnDemand); @@ -863,8 +859,6 @@ BASE_DECLARE_FEATURE(kVirtualKeyboardBorderedKey); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kVirtualKeyboardRoundCorners); -COMPONENT_EXPORT(ASH_CONSTANTS) -BASE_DECLARE_FEATURE(kVirtualKeyboardRemoveNacl); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kWakeOnWifiAllowed); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kWallpaperFastRefresh); COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts b/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts index 3876dea..37bd60ee 100644 --- a/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts +++ b/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts
@@ -10,6 +10,7 @@ import * as state from '../state.js'; import { CameraSuspendError, + CropRegionRect, ErrorLevel, ErrorType, Facing, @@ -815,6 +816,24 @@ } /** + * Sets the crop region for the configured stream on camera with |deviceId|. + */ + async setCropRegion(deviceId: string, cropRegion: CropRegionRect): + Promise<void> { + const device = await this.getDevice(deviceId); + await device.setCropRegion(cropRegion); + } + + /** + * Resets the crop region for the camera with |deviceId| to let the camera + * stream back to full frame. + */ + async resetCropRegion(deviceId: string): Promise<void> { + const device = await this.getDevice(deviceId); + await device.resetCropRegion(); + } + + /** * Initializes the singleton instance. * * This should be called before all invocation of static getInstance() and
diff --git a/ash/webui/camera_app_ui/resources/js/type.ts b/ash/webui/camera_app_ui/resources/js/type.ts index f1d3db5..c2a6c800 100644 --- a/ash/webui/camera_app_ui/resources/js/type.ts +++ b/ash/webui/camera_app_ui/resources/js/type.ts
@@ -505,4 +505,15 @@ CANNOT_START = 'cannot-start', } +/** + * A rectangle representing a crop region with size (width, height) and having + * the top-left coordinate at (x, y). + */ +export interface CropRegionRect { + height: number; + width: number; + x: number; + y: number; +} + export type Awaitable<T> = PromiseLike<T>|T;
diff --git a/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts b/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts index 7ab994e..48d0270 100644 --- a/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts +++ b/ash/webui/shortcut_customization_ui/resources/js/fake_shortcut_provider.ts
@@ -33,11 +33,11 @@ private preventProcessingAcceleratorsCallCount: number = 0; private addAcceleratorCallCount: number = 0; private removeAcceleratorCallCount: number = 0; - private lastRecordedUserAction: UserAction|undefined; - private lastRecordedMainCategory: AcceleratorCategory|undefined; - private lastRecoredEditDialogActions: EditDialogCompletedActions|undefined; + private lastRecordedUserAction: UserAction; + private lastRecordedMainCategory: AcceleratorCategory; + private lastRecoredEditDialogActions: EditDialogCompletedActions; private lastRecordedIsAdd: boolean = false; - private lastRecorededSubactions: Subactions|undefined; + private lastRecorededSubactions: Subactions; constructor() { this.methods = new FakeMethodResolver(); @@ -76,11 +76,6 @@ this.preventProcessingAcceleratorsCallCount = 0; this.addAcceleratorCallCount = 0; this.removeAcceleratorCallCount = 0; - this.lastRecordedUserAction = undefined; - this.lastRecordedMainCategory = undefined; - this.lastRecoredEditDialogActions = undefined; - this.lastRecordedIsAdd = false; - this.lastRecorededSubactions = undefined; this.observables = new FakeObservables(); this.registerObservables(); } @@ -192,11 +187,11 @@ this.lastRecoredEditDialogActions = completed_actions; } - getLastEditDialogCompletedActions(): EditDialogCompletedActions|undefined { + getLastEditDialogCompletedActions(): EditDialogCompletedActions { return this.lastRecoredEditDialogActions; } - getLatestRecordedAction(): UserAction|undefined { + getLatestRecordedAction(): UserAction { return this.lastRecordedUserAction; } @@ -204,7 +199,7 @@ this.lastRecordedMainCategory = category; } - getLatestMainCategoryNavigated(): AcceleratorCategory|undefined { + getLatestMainCategoryNavigated(): AcceleratorCategory { return this.lastRecordedMainCategory; } @@ -217,7 +212,7 @@ return this.lastRecordedIsAdd; } - getLastRecordedSubactions(): Subactions|undefined { + getLastRecordedSubactions(): Subactions { return this.lastRecorededSubactions; }
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index f501cd92..93da1e4 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -90,10 +90,11 @@ using chromeos::WindowStateType; -// Three fixed position ratios of the divider, which means the divider can -// always be moved to these three positions. -constexpr float kFixedPositionRatios[] = {0.f, chromeos::kDefaultSnapRatio, - 1.0f}; +// Five fixed position ratios of the divider, which means the divider can +// always be moved to these five positions. +constexpr float kFixedPositionRatios[] = {0.f, chromeos::kOneThirdSnapRatio, + chromeos::kDefaultSnapRatio, + chromeos::kTwoThirdSnapRatio, 1.0f}; // The black scrim starts to fade in when the divider is moved past the two // optional positions (`chromeos::kOneThirdSnapRatio`, @@ -781,7 +782,6 @@ aura::Window* previous_snapped_window = nullptr; aura::Window* other_window = nullptr; if (snap_position == SnapPosition::kPrimary) { - other_window = secondary_window_; if (primary_window_ != window) { previous_snapped_window = primary_window_; StopObserving(SnapPosition::kPrimary); @@ -793,18 +793,21 @@ secondary_window_ = nullptr; default_snap_position_ = SnapPosition::kPrimary; } + // `other_window` must be set last, since we may have removed + // `secondary_window_`. + other_window = secondary_window_; } else if (snap_position == SnapPosition::kSecondary) { - other_window = primary_window_; + // See above comments. if (secondary_window_ != window) { previous_snapped_window = secondary_window_; StopObserving(SnapPosition::kSecondary); secondary_window_ = window; } if (primary_window_ == window) { - // See above comment. primary_window_ = nullptr; default_snap_position_ = SnapPosition::kSecondary; } + other_window = primary_window_; } StartObserving(window); @@ -829,16 +832,14 @@ std::make_unique<SplitViewDivider>(this, divider_position_); } - if (split_view_divider_) { - divider_position_ = GetClosestFixedDividerPosition(); - split_view_divider_->UpdateDividerBounds(); - } - + // This must be done before we push `divider_position_` to the closest fixed + // ratio, since the minimum size will be respected there. + const int new_divider_position = GetClosestFixedDividerPosition(); const bool total_size_exceeds_work_area = divider_position_ + kSplitviewDividerShortSideLength + GetMinimumWindowLength(other_window, IsLayoutHorizontal(window)) > GetDividerPositionUpperLimit(root_window_); - if (primary_window_ && secondary_window_ && total_size_exceeds_work_area) { + if (split_view_divider_ && other_window && total_size_exceeds_work_area) { // If `other_window` can't fit in the opposite position, set // `divider_snap_animation_` to Hide then Show, to give off the // impression of bouncing the divider back to `old_divider_position`. @@ -846,12 +847,17 @@ // bounce out then in. tablet_resize_mode_ = TabletResizeMode::kFast; divider_snap_animation_ = std::make_unique<DividerSnapAnimation>( - this, divider_position_, old_divider_position, + this, new_divider_position, old_divider_position, 2 * kBouncingAnimationOneWayDuration, gfx::Tween::FAST_OUT_SLOW_IN_3); divider_snap_animation_->Hide(); divider_snap_animation_->Show(); } + if (split_view_divider_) { + divider_position_ = new_divider_position; + split_view_divider_->UpdateDividerBounds(); + } + base::RecordAction(base::UserMetricsAction("SplitView_SnapWindow")); } @@ -1009,7 +1015,6 @@ const bool is_divider_animating = IsDividerAnimating(); if ((IsResizingWithDivider() || is_divider_animating) && end_reason != EndReason::kRootWindowDestroyed) { - split_view_divider_->set_is_resizing_with_divider(false); if (is_divider_animating) { // Don't call StopAndShoveAnimatedDivider as it will call observers. StopSnapAnimation(); @@ -2226,7 +2231,6 @@ // view. const bool is_divider_animating = IsDividerAnimating(); if (IsResizingWithDivider() || is_divider_animating) { - split_view_divider_->set_is_resizing_with_divider(false); if (is_divider_animating) { StopAndShoveAnimatedDivider(); } @@ -2296,13 +2300,14 @@ static_cast<float>(min_left_size) / divider_upper_limit; const float min_size_right_ratio = static_cast<float>(min_right_size) / divider_upper_limit; - if (min_size_left_ratio <= chromeos::kOneThirdSnapRatio) { - out_position_ratios->push_back(chromeos::kOneThirdSnapRatio); + if (min_size_left_ratio > chromeos::kOneThirdSnapRatio) { + // If `primary_window_` can't fit in 1/3, remove 0.33f divider position. + base::Erase(*out_position_ratios, chromeos::kOneThirdSnapRatio); } - if (min_size_right_ratio <= chromeos::kOneThirdSnapRatio) { - out_position_ratios->push_back(chromeos::kTwoThirdSnapRatio); + if (min_size_right_ratio > chromeos::kOneThirdSnapRatio) { + // If `secondary_window_` can't fit in 1/3, remove 0.67f divider position. + base::Erase(*out_position_ratios, chromeos::kTwoThirdSnapRatio); } - // Remove 0.5f if a window cannot be snapped. We can get into this state by // snapping a window to two thirds. if (min_size_left_ratio > chromeos::kDefaultSnapRatio || @@ -2557,7 +2562,11 @@ void SplitViewController::EndResizeWithDividerImpl() { DCHECK(InSplitViewMode()); - DCHECK(!IsResizingWithDivider()); + if (split_view_divider_) { + // TODO(b/315854755): Move `DividerSnapAnimation` to `SplitViewDivider` and + // see if we can remove this. + split_view_divider_->set_is_resizing_with_divider(false); + } EndTabletResizeImpl(); presentation_time_recorder_.reset(); @@ -2639,9 +2648,9 @@ void SplitViewController::OnTabletModeEnding() { split_view_type_ = SplitViewType::kClamshellType; + // `OnTabletModeEnding()` can also be called during test teardown. const bool is_divider_animating = IsDividerAnimating(); if (IsResizingWithDivider() || is_divider_animating) { - split_view_divider_->set_is_resizing_with_divider(false); if (is_divider_animating) { StopAndShoveAnimatedDivider(); }
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index b6b7147..28479c92 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -3326,8 +3326,9 @@ } // Tests that, if two windows are snapped and one window has min size, trying to -// partial split the other window opens Overview and updates bounds correctly. -TEST_F(SplitViewControllerTest, SnapWindowWithMinSizeOpensOverview) { +// partial split the other window starts a bounce animation. +TEST_F(SplitViewControllerTest, + SnapWindowWithMinSizeStartsDividerSnapAnimation) { const gfx::Rect bounds(0, 0, 400, 400); std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); std::unique_ptr<aura::Window> window2(CreateWindow(bounds)); @@ -3349,6 +3350,7 @@ WindowSnapWMEvent snap_primary_two_third(WM_EVENT_SNAP_PRIMARY, chromeos::kTwoThirdSnapRatio); WindowState::Get(window1.get())->OnWMEvent(&snap_primary_two_third); + ASSERT_TRUE(IsDividerAnimating()); SkipDividerSnapAnimation(); gfx::Rect divider_bounds = split_view_divider()->GetDividerBoundsInScreen(/*is_dragging=*/false); @@ -3360,6 +3362,39 @@ window2->bounds().width() + kSplitviewDividerShortSideLength / 2); } +// Tests no crash on tablet <-> clamshell transition after a divider snap +// animation is started. +TEST_F(SplitViewControllerTest, NoCrashAfterDividerSnapAnimation) { + ui::ScopedAnimationDurationScaleMode animation_scale( + ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); + const gfx::Rect bounds(0, 0, 400, 400); + std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); + std::unique_ptr<aura::Window> window2(CreateWindow(bounds)); + + // Snap 2 windows in split view. Set `window2` min length to be 0.4 of + // the work area so it can't fit in 1/3 split. + gfx::Rect work_area_bounds = + screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( + window1.get()); + aura::test::TestWindowDelegate* delegate2 = + static_cast<aura::test::TestWindowDelegate*>(window2->delegate()); + delegate2->set_minimum_size( + gfx::Size(work_area_bounds.width() * 0.4f, work_area_bounds.height())); + WindowSnapWMEvent snap_primary(WM_EVENT_SNAP_PRIMARY); + WindowState::Get(window1.get())->OnWMEvent(&snap_primary); + WindowSnapWMEvent snap_secondary(WM_EVENT_SNAP_SECONDARY); + WindowState::Get(window2.get())->OnWMEvent(&snap_secondary); + + // Since `window2` can't fit in 1/3, we start a divider snap animation. + WindowSnapWMEvent snap_primary_two_third(WM_EVENT_SNAP_PRIMARY, + chromeos::kTwoThirdSnapRatio); + WindowState::Get(window1.get())->OnWMEvent(&snap_primary_two_third); + ASSERT_TRUE(IsDividerAnimating()); + + // Transition to clamshell mode. Test no crash. + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false); +} + // Tests that resnapping a snapped window to its opposite snap position will // start the partial overview and divider will be at the correct position. See // crash at b/311216394. @@ -3378,6 +3413,7 @@ delegate2->set_minimum_size( gfx::Size(work_area_bounds.width() * 0.4f, work_area_bounds.height())); + // Snap `window1` to primary 2/3. WindowSnapWMEvent snap_primary_two_thirds(WM_EVENT_SNAP_PRIMARY, chromeos::kTwoThirdSnapRatio); WindowState::Get(window1.get())->OnWMEvent(&snap_primary_two_thirds); @@ -3390,6 +3426,8 @@ ->split_view_overview_session(); EXPECT_TRUE(split_view_overview_session); + // Select `window2` from overview. Since its minimum size is greater than 1/3, + // it gets snapped at 1/2. auto* item2 = GetOverviewItemForWindow(window2.get()); auto* event_generator = GetEventGenerator(); event_generator->MoveMouseTo( @@ -3398,15 +3436,21 @@ EXPECT_EQ(split_view_controller()->state(), SplitViewController::State::kBothSnapped); + EXPECT_EQ( + work_area_bounds.width() * 0.5f - kSplitviewDividerShortSideLength / 2, + split_view_controller()->divider_position()); EXPECT_EQ(work_area_bounds.width() * 0.5f, window1->bounds().width() + kSplitviewDividerShortSideLength / 2); EXPECT_EQ(work_area_bounds.width() * 0.5f, window2->bounds().width() + kSplitviewDividerShortSideLength / 2); + // Re-snap `window2` to primary 2/3. WindowSnapWMEvent snap_secondary_two_thirds(WM_EVENT_SNAP_PRIMARY, chromeos::kTwoThirdSnapRatio); WindowState::Get(window2.get())->OnWMEvent(&snap_secondary_two_thirds); - SkipDividerSnapAnimation(); + EXPECT_NEAR(work_area_bounds.width() * 0.67f, + split_view_controller()->divider_position(), + kSplitviewDividerShortSideLength); EXPECT_NEAR(work_area_bounds.width() * 0.67f, window2->bounds().width(), kSplitviewDividerShortSideLength); EXPECT_TRUE(overview_controller->InOverviewSession());
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index 3af8250..4c76fee 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -38,8 +38,8 @@ "javatests/src/org/chromium/chrome/browser/keyboard_accessory/PasswordGenerationIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetViewTest.java", - "javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryTestHelper.java", + "javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetRenderTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabViewTest.java", @@ -48,7 +48,6 @@ "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessoryIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/CreditCardAccessorySheetViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryIntegrationTest.java", - "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java", ]
diff --git a/chrome/android/features/keyboard_accessory/internal/BUILD.gn b/chrome/android/features/keyboard_accessory/internal/BUILD.gn index 16b3f842..8bb1b88 100644 --- a/chrome/android/features/keyboard_accessory/internal/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/internal/BUILD.gn
@@ -84,10 +84,10 @@ "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMetricsRecorder.java", - "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernView.java", - "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryRecyclerViewMcp.java", + "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java", + "java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupCoordinator.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupMediator.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupProperties.java", @@ -120,7 +120,6 @@ "java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryInfoView.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetMediator.java", - "java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PromoCodeAccessoryInfoView.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/utils/InsecureFillingDialogUtils.java", @@ -136,13 +135,12 @@ "java/res/layout/address_accessory_sheet.xml", "java/res/layout/all_passwords_bottom_sheet.xml", "java/res/layout/credit_card_accessory_sheet.xml", - "java/res/layout/keyboard_accessory_action_modern.xml", + "java/res/layout/keyboard_accessory.xml", + "java/res/layout/keyboard_accessory_action.xml", "java/res/layout/keyboard_accessory_buttons.xml", - "java/res/layout/keyboard_accessory_modern.xml", "java/res/layout/keyboard_accessory_sheet.xml", "java/res/layout/keyboard_accessory_sheet_tab_address_info.xml", "java/res/layout/keyboard_accessory_sheet_tab_credit_card_info.xml", - "java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml", "java/res/layout/keyboard_accessory_sheet_tab_legacy_title.xml", "java/res/layout/keyboard_accessory_sheet_tab_option_toggle.xml", "java/res/layout/keyboard_accessory_sheet_tab_password_info.xml", @@ -151,8 +149,6 @@ "java/res/layout/keyboard_accessory_suggestion.xml", "java/res/layout/password_accessory_passkey_chip.xml", "java/res/layout/password_accessory_sheet.xml", - "java/res/layout/password_accessory_sheet_label.xml", - "java/res/layout/password_accessory_sheet_legacy_option.xml", "java/res/layout/password_accessory_sheet_option.xml", "java/res/values/dimens.xml", "java/res/values/styles.xml",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory.xml similarity index 96% rename from chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml rename to chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory.xml index beb38b59..2475952e 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_modern.xml +++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory.xml
@@ -5,7 +5,7 @@ found in the LICENSE file. --> -<org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryModernView +<org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/keyboard_accessory" @@ -47,4 +47,4 @@ </LinearLayout> -</org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryModernView> +</org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryView>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_action_modern.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_action.xml similarity index 100% rename from chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_action_modern.xml rename to chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_action.xml
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml deleted file mode 100644 index ecbbcfe..0000000 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/keyboard_accessory_sheet_tab_legacy_password_info.xml +++ /dev/null
@@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2018 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:gravity="center_vertical|start" - android:fillViewport="true" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:orientation="vertical"> - - <TextView - android:id="@+id/suggestion_text" - android:gravity="center_vertical|start" - android:fillViewport="true" - android:minHeight="@dimen/keyboard_accessory_suggestion_height" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:textAppearance="@style/TextAppearance.TextLarge.Primary"/> - - <TextView - android:id="@+id/password_text" - android:gravity="center_vertical|start" - android:fillViewport="true" - android:minHeight="@dimen/keyboard_accessory_suggestion_height" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:textAppearance="@style/TextAppearance.TextLarge.Primary"/> - -</LinearLayout>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet_label.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet_label.xml deleted file mode 100644 index 4a31d47..0000000 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet_label.xml +++ /dev/null
@@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2018 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:gravity="center_vertical|start" - android:fillViewport="true" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:orientation="vertical"> - - <View style="@style/HorizontalDivider" - android:layout_marginTop="0dp" - android:layout_marginBottom="@dimen/keyboard_accessory_sheet_padding" /> - - <org.chromium.ui.widget.TextViewWithLeading - android:id="@+id/tab_title" - android:paddingStart="@dimen/keyboard_accessory_suggestion_padding" - android:paddingEnd="@dimen/keyboard_accessory_suggestion_padding" - android:paddingTop="@dimen/keyboard_accessory_suggestion_offset" - android:paddingBottom="@dimen/keyboard_accessory_suggestion_offset" - android:gravity="center_vertical|start" - android:textAppearance="@style/TextAppearance.TextLarge.Secondary" - android:minHeight="@dimen/keyboard_accessory_height" - app:leading="@dimen/text_size_large_leading" - android:layout_height="wrap_content" - android:layout_width="match_parent"/> -</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet_legacy_option.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet_legacy_option.xml deleted file mode 100644 index cce940bf..0000000 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet_legacy_option.xml +++ /dev/null
@@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright 2018 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/footer_command" - android:gravity="center_vertical|start" - android:fillViewport="true" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:paddingTop="0dp" - android:paddingBottom="0dp" - android:orientation="vertical"> - - <TextView - android:id="@+id/footer_text" - android:paddingStart="@dimen/keyboard_accessory_suggestion_padding" - android:paddingEnd="@dimen/keyboard_accessory_suggestion_padding" - android:fillViewport="true" - android:minHeight="@dimen/keyboard_accessory_suggestion_height" - android:gravity="center_vertical|start" - android:textAppearance="@style/TextAppearance.TextLarge.Primary" - android:layout_height="wrap_content" - android:layout_width="match_parent" - android:background="?android:attr/selectableItemBackground"/> - -</LinearLayout>
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java index 32ac3b1..3ff82d4 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java
@@ -48,7 +48,7 @@ AsyncViewStub barStub) { if (barStub == null || sheetStub == null) return; // The manual filling isn't needed. // TODO(crbug.com/1448820): Initialize in the xml resources file. - barStub.setLayoutResource(R.layout.keyboard_accessory_modern); + barStub.setLayoutResource(R.layout.keyboard_accessory); sheetStub.setLayoutResource(R.layout.keyboard_accessory_sheet); barStub.setShouldInflateOnBackgroundThread(true); sheetStub.setShouldInflateOnBackgroundThread(true);
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java index cc638544..48d4110 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java
@@ -15,8 +15,8 @@ import org.chromium.base.TraceEvent; import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType; import org.chromium.chrome.browser.keyboard_accessory.R; -import org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryModernViewBinder.BarItemViewHolder; import org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BarItem; +import org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryViewBinder.BarItemViewHolder; import org.chromium.chrome.browser.keyboard_accessory.button_group_component.KeyboardAccessoryButtonGroupCoordinator; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; import org.chromium.chrome.browser.keyboard_accessory.data.Provider; @@ -40,7 +40,7 @@ private final KeyboardAccessoryMediator mMediator; private final KeyboardAccessoryButtonGroupCoordinator mButtonGroup; private final PropertyModel mModel; - private KeyboardAccessoryModernView mView; + private KeyboardAccessoryView mView; /** * The interface to notify consumers about keyboard accessories visibility. E.g: the animation @@ -133,7 +133,7 @@ KeyboardAccessoryButtonGroupCoordinator buttonGroup, BarVisibilityDelegate barVisibilityDelegate, AccessorySheetCoordinator.SheetVisibilityDelegate sheetVisibilityDelegate, - ViewProvider<KeyboardAccessoryModernView> viewProvider) { + ViewProvider<KeyboardAccessoryView> viewProvider) { mButtonGroup = buttonGroup; mModel = KeyboardAccessoryProperties.defaultModelBuilder().build(); mMediator = @@ -147,7 +147,7 @@ mButtonGroup.setTabObserver(mMediator); LazyConstructionPropertyMcp.create( - mModel, VISIBLE, viewProvider, KeyboardAccessoryModernViewBinder::bind); + mModel, VISIBLE, viewProvider, KeyboardAccessoryViewBinder::bind); KeyboardAccessoryMetricsRecorder.registerKeyboardAccessoryModelMetricsObserver(mModel); } @@ -165,7 +165,7 @@ BarItem::getViewType, BarItemViewHolder::bind, BarItemViewHolder::recycle), - KeyboardAccessoryModernViewBinder::create); + KeyboardAccessoryViewBinder::create); } public void closeActiveTab() { @@ -234,7 +234,7 @@ // TODO(fhorschig): Consider allow LazyConstructionPropertyMcp to propagate updates once the // view exists. Currently it doesn't, so we need this ugly explicit binding. if (mView != null) { - KeyboardAccessoryModernViewBinder.bind(mModel, mView, SKIP_CLOSING_ANIMATION); + KeyboardAccessoryViewBinder.bind(mModel, mView, SKIP_CLOSING_ANIMATION); } }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java index c43129a..04e21332 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java
@@ -51,7 +51,7 @@ static final WritableBooleanPropertyKey HAS_SUGGESTIONS = new WritableBooleanPropertyKey("has_suggestions"); - static final WritableObjectPropertyKey<KeyboardAccessoryModernView.AnimationListener> + static final WritableObjectPropertyKey<KeyboardAccessoryView.AnimationListener> ANIMATION_LISTENER = new WritableObjectPropertyKey<>("animation_listener"); static PropertyModel.Builder defaultModelBuilder() {
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java similarity index 98% rename from chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernView.java rename to chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java index 6144e6df..0909cbfe 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernView.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java
@@ -34,7 +34,7 @@ * The Accessory sitting above the keyboard and below the content area. It is used for autofill * suggestions and manual entry points assisting the user in filling forms. */ -class KeyboardAccessoryModernView extends LinearLayout { +class KeyboardAccessoryView extends LinearLayout { private static final int ARRIVAL_ANIMATION_DURATION_MS = 300; private static final float ARRIVAL_ANIMATION_BOUNCE_LENGTH_DIP = 200f; private static final float ARRIVAL_ANIMATION_TENSION = 1f; @@ -153,7 +153,7 @@ } /** Constructor for inflating from XML. */ - public KeyboardAccessoryModernView(Context context, AttributeSet attrs) { + public KeyboardAccessoryView(Context context, AttributeSet attrs) { super(context, attrs); }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java similarity index 97% rename from chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java rename to chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java index 14a8421eb..e3a55e9 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java
@@ -47,7 +47,7 @@ * Observes {@link KeyboardAccessoryProperties} changes (like a newly available tab) and modifies * the view accordingly. */ -class KeyboardAccessoryModernViewBinder { +class KeyboardAccessoryViewBinder { static BarItemViewHolder create(ViewGroup parent, @BarItem.Type int viewType) { switch (viewType) { case BarItem.Type.SUGGESTION: @@ -55,7 +55,7 @@ case BarItem.Type.TAB_LAYOUT: return new SheetOpenerViewHolder(parent); case BarItem.Type.ACTION_BUTTON: - return new BarItemTextViewHolder(parent, R.layout.keyboard_accessory_action_modern); + return new BarItemTextViewHolder(parent, R.layout.keyboard_accessory_action); case BarItem.Type.ACTION_CHIP: return new BarItemActionChipViewHolder(parent); } @@ -241,11 +241,10 @@ * Tries to bind the given property to the given view by using the value in the given model. * * @param model A {@link PropertyModel}. - * @param view A {@link KeyboardAccessoryModernView}. + * @param view A {@link KeyboardAccessoryView}. * @param propertyKey A {@link PropertyKey}. */ - static void bind( - PropertyModel model, KeyboardAccessoryModernView view, PropertyKey propertyKey) { + static void bind(PropertyModel model, KeyboardAccessoryView view, PropertyKey propertyKey) { if (propertyKey == BAR_ITEMS) { view.setBarItemsAdapter( KeyboardAccessoryCoordinator.createBarItemsAdapter(model.get(BAR_ITEMS)));
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupView.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupView.java index 462a2c85..640bd9a 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupView.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/button_group_component/KeyboardAccessoryButtonGroupView.java
@@ -78,7 +78,7 @@ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - // The parent, which is KeyboardAccessoryModernView's recycler view may measure + // The parent, which is KeyboardAccessoryView's recycler view may measure // StickyLastItemDecoration offsets before the buttons are added. Notify the parent to // recalculate the offset during each measurement. // TODO(crbug.com/1424789): Find a better alternative.
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java index 600f10f..3e59b37c 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetCoordinator.java
@@ -56,8 +56,7 @@ @Override public void onTabCreated(ViewGroup view) { super.onTabCreated(view); - PasswordAccessorySheetModernViewBinder.initializeView( - (RecyclerView) view, mModel.get(ITEMS)); + PasswordAccessorySheetViewBinder.initializeView((RecyclerView) view, mModel.get(ITEMS)); } @Override @@ -73,13 +72,14 @@ } /** - * Creates an adapter to an {@link PasswordAccessorySheetViewBinder} that is wired - * up to a model change processor listening to the {@link AccessorySheetTabItemsModel}. + * Creates an adapter to an {@link PasswordAccessorySheetViewBinder} that is wired up to the + * model change processor which listens to the {@link AccessorySheetTabItemsModel}. + * * @param model the {@link AccessorySheetTabItemsModel} the adapter gets its data from. - * @return Returns a fully initialized and wired adapter to a PasswordAccessorySheetViewBinder. + * @return Returns an {@link PasswordAccessorySheetViewBinder} wired to a MCP. */ static RecyclerViewAdapter<AccessorySheetTabViewBinder.ElementViewHolder, Void> createAdapter( - AccessorySheetTabItemsModel model) { + ListModel<AccessorySheetDataPiece> model) { return new RecyclerViewAdapter<>( new SimpleRecyclerViewMcp<>( model, @@ -87,20 +87,4 @@ AccessorySheetTabViewBinder.ElementViewHolder::bind), PasswordAccessorySheetViewBinder::create); } - - /** - * Creates an adapter to an {@link PasswordAccessorySheetModernViewBinder} that is wired up to - * the model change processor which listens to the {@link AccessorySheetTabItemsModel}. - * @param model the {@link AccessorySheetTabItemsModel} the adapter gets its data from. - * @return Returns an {@link PasswordAccessorySheetModernViewBinder} wired to a MCP. - */ - static RecyclerViewAdapter<AccessorySheetTabViewBinder.ElementViewHolder, Void> - createModernAdapter(ListModel<AccessorySheetDataPiece> model) { - return new RecyclerViewAdapter<>( - new SimpleRecyclerViewMcp<>( - model, - AccessorySheetDataPiece::getType, - AccessorySheetTabViewBinder.ElementViewHolder::bind), - PasswordAccessorySheetModernViewBinder::create); - } }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java deleted file mode 100644 index 145cc9a8..0000000 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java +++ /dev/null
@@ -1,120 +0,0 @@ -// Copyright 2018 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.keyboard_accessory.sheet_tabs; - -import static org.chromium.components.embedder_support.util.UrlUtilities.stripScheme; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.text.method.PasswordTransformationMethod; -import android.view.View; -import android.view.ViewGroup; - -import androidx.recyclerview.widget.RecyclerView; - -import org.chromium.chrome.browser.keyboard_accessory.R; -import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; -import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; -import org.chromium.chrome.browser.keyboard_accessory.helper.FaviconHelper; -import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabItemsModel.AccessorySheetDataPiece; -import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder; -import org.chromium.chrome.browser.keyboard_accessory.utils.InsecureFillingDialogUtils; -import org.chromium.components.browser_ui.widget.chips.ChipView; -import org.chromium.ui.modelutil.ListModel; - -/** - * This stateless class provides methods to bind a {@link ListModel<AccessorySheetDataPiece>} - * to the {@link RecyclerView} used as view of a tab for the accessory sheet component. - */ -class PasswordAccessorySheetModernViewBinder { - static ElementViewHolder create(ViewGroup parent, @AccessorySheetDataPiece.Type int viewType) { - switch (viewType) { - case AccessorySheetDataPiece.Type.PASSKEY_SECTION: - return new PasskeyChipViewHolder(parent); - case AccessorySheetDataPiece.Type.PASSWORD_INFO: - return new PasswordInfoViewHolder(parent); - case AccessorySheetDataPiece.Type.TITLE: - return new AccessorySheetTabViewBinder.TitleViewHolder( - parent, R.layout.keyboard_accessory_sheet_tab_title); - case AccessorySheetDataPiece.Type.FOOTER_COMMAND: - case AccessorySheetDataPiece.Type.OPTION_TOGGLE: - return AccessorySheetTabViewBinder.create(parent, viewType); - } - assert false : "Unhandled type of data piece: " + viewType; - return null; - } - - /** Holds a clickable {@link ChipView} that represents a Passkey. */ - static class PasskeyChipViewHolder - extends ElementViewHolder<KeyboardAccessoryData.PasskeySection, ViewGroup> { - PasskeyChipViewHolder(ViewGroup parent) { - super(parent, R.layout.password_accessory_passkey_chip); - } - - @Override - protected void bind(KeyboardAccessoryData.PasskeySection passkeySection, ViewGroup view) { - ChipView chip = view.findViewById(R.id.keyboard_accessory_sheet_chip); - chip.getPrimaryTextView().setText(passkeySection.getDisplayName()); - chip.getPrimaryTextView().setContentDescription(passkeySection.getDisplayName()); - chip.getSecondaryTextView().setText(R.string.password_accessory_passkey_label); - chip.setOnClickListener((unused) -> passkeySection.triggerSelection()); - } - } - - /** Holds a TextView that represents a list entry. */ - static class PasswordInfoViewHolder - extends ElementViewHolder<KeyboardAccessoryData.UserInfo, PasswordAccessoryInfoView> { - String mFaviconRequestOrigin; - - PasswordInfoViewHolder(ViewGroup parent) { - super(parent, R.layout.keyboard_accessory_sheet_tab_password_info); - } - - @Override - protected void bind(KeyboardAccessoryData.UserInfo info, PasswordAccessoryInfoView view) { - bindChipView(view.getUsername(), info.getFields().get(0), view.getContext()); - bindChipView(view.getPassword(), info.getFields().get(1), view.getContext()); - - view.getTitle().setVisibility(info.isExactMatch() ? View.GONE : View.VISIBLE); - // Strip the trailing slash (for aesthetic reasons): - view.getTitle().setText(stripScheme(info.getOrigin()).replaceFirst("/$", "")); - - // Set the default icon, then try to get a better one. - mFaviconRequestOrigin = info.getOrigin(); // Save the origin for returning callback. - FaviconHelper faviconHelper = FaviconHelper.create(view.getContext()); - view.setIconForBitmap(faviconHelper.getDefaultIcon(info.getOrigin())); - faviconHelper.fetchFavicon(info.getOrigin(), d -> setIcon(view, info.getOrigin(), d)); - } - - private void setIcon( - PasswordAccessoryInfoView view, String requestOrigin, Drawable drawable) { - // Only set the icon if the origin hasn't changed since this view last requested an - // icon. Since the Views are recycled, an old callback can target a new view. - if (requestOrigin.equals(mFaviconRequestOrigin)) view.setIconForBitmap(drawable); - } - - void bindChipView(ChipView chip, UserInfoField field, Context context) { - chip.getPrimaryTextView() - .setTransformationMethod( - field.isObfuscated() ? new PasswordTransformationMethod() : null); - chip.getPrimaryTextView().setText(field.getDisplayText()); - chip.getPrimaryTextView().setContentDescription(field.getA11yDescription()); - View.OnClickListener listener = null; - if (field.isSelectable()) { - listener = src -> field.triggerSelection(); - } else if (field.isObfuscated()) { - listener = src -> InsecureFillingDialogUtils.showWarningDialog(context); - } - chip.setOnClickListener(listener); - chip.setClickable(listener != null); - chip.setEnabled(listener != null); - } - } - - static void initializeView(RecyclerView view, AccessorySheetTabItemsModel model) { - view.setAdapter(PasswordAccessorySheetCoordinator.createModernAdapter(model)); - view.addItemDecoration(new DynamicInfoViewBottomSpacer(PasswordAccessoryInfoView.class)); - } -}
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java index 014efd5..9dee9f9 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java
@@ -4,206 +4,117 @@ package org.chromium.chrome.browser.keyboard_accessory.sheet_tabs; -import static org.chromium.ui.base.LocalizationUtils.isLayoutRtl; +import static org.chromium.components.embedder_support.util.UrlUtilities.stripScheme; import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.text.method.PasswordTransformationMethod; -import android.view.Gravity; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; -import androidx.annotation.Nullable; -import androidx.core.view.ViewCompat; import androidx.recyclerview.widget.RecyclerView; import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; -import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.FooterCommand; import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.helper.FaviconHelper; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabItemsModel.AccessorySheetDataPiece; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder; -import org.chromium.ui.HorizontalListDividerDrawable; +import org.chromium.chrome.browser.keyboard_accessory.utils.InsecureFillingDialogUtils; +import org.chromium.components.browser_ui.widget.chips.ChipView; import org.chromium.ui.modelutil.ListModel; /** - * This stateless class provides methods to bind the items in a {@link ListModel <Item>} - * to the {@link RecyclerView} used as view of the Password accessory sheet component. + * This stateless class provides methods to bind a {@link ListModel<AccessorySheetDataPiece>} + * to the {@link RecyclerView} used as view of a tab for the accessory sheet component. */ class PasswordAccessorySheetViewBinder { static ElementViewHolder create(ViewGroup parent, @AccessorySheetDataPiece.Type int viewType) { switch (viewType) { - case AccessorySheetDataPiece.Type.TITLE: - return new PasswordsTitleViewHolder(parent); + case AccessorySheetDataPiece.Type.PASSKEY_SECTION: + return new PasskeyChipViewHolder(parent); case AccessorySheetDataPiece.Type.PASSWORD_INFO: - return new PasswordsInfoViewHolder(parent); + return new PasswordInfoViewHolder(parent); + case AccessorySheetDataPiece.Type.TITLE: + return new AccessorySheetTabViewBinder.TitleViewHolder( + parent, R.layout.keyboard_accessory_sheet_tab_title); case AccessorySheetDataPiece.Type.FOOTER_COMMAND: - return new FooterCommandViewHolder(parent); + case AccessorySheetDataPiece.Type.OPTION_TOGGLE: + return AccessorySheetTabViewBinder.create(parent, viewType); } assert false : "Unhandled type of data piece: " + viewType; return null; } - /** Holds a the TextView with the title of the sheet and a divider for the accessory bar. */ - static class PasswordsTitleViewHolder extends ElementViewHolder<String, LinearLayout> { - PasswordsTitleViewHolder(ViewGroup parent) { - super(parent, R.layout.password_accessory_sheet_label); + /** Holds a clickable {@link ChipView} that represents a Passkey. */ + static class PasskeyChipViewHolder + extends ElementViewHolder<KeyboardAccessoryData.PasskeySection, ViewGroup> { + PasskeyChipViewHolder(ViewGroup parent) { + super(parent, R.layout.password_accessory_passkey_chip); } @Override - protected void bind(String displayText, LinearLayout view) { - TextView titleView = view.findViewById(R.id.tab_title); - titleView.setText(displayText); - titleView.setContentDescription(displayText); + protected void bind(KeyboardAccessoryData.PasskeySection passkeySection, ViewGroup view) { + ChipView chip = view.findViewById(R.id.keyboard_accessory_sheet_chip); + chip.getPrimaryTextView().setText(passkeySection.getDisplayName()); + chip.getPrimaryTextView().setContentDescription(passkeySection.getDisplayName()); + chip.getSecondaryTextView().setText(R.string.password_accessory_passkey_label); + chip.setOnClickListener((unused) -> passkeySection.triggerSelection()); } } - /** - * Holds a TextView that represents a bottom command and is separated to the top by a divider. - */ - static class FooterCommandViewHolder extends ElementViewHolder<FooterCommand, LinearLayout> { - public static class DynamicTopDivider extends RecyclerView.ItemDecoration { - private final int mAccessoryPadding; - private final int mDividerHeight; + /** Holds a TextView that represents a list entry. */ + static class PasswordInfoViewHolder + extends ElementViewHolder<KeyboardAccessoryData.UserInfo, PasswordAccessoryInfoView> { + String mFaviconRequestOrigin; - DynamicTopDivider(Context context) { - var resources = context.getResources(); - mAccessoryPadding = - resources.getDimensionPixelOffset( - R.dimen.keyboard_accessory_suggestion_padding); - mDividerHeight = resources.getDimensionPixelSize(R.dimen.divider_height); - } - - @Override - public void getItemOffsets( - Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { - super.getItemOffsets(outRect, view, parent, state); - if (view.getId() != R.id.footer_command) return; - int previous = parent.indexOfChild(view) - 1; - if (previous < 0) return; - if (parent.getChildAt(previous).getId() == R.id.footer_command) return; - outRect.top = mAccessoryPadding + mDividerHeight; - } - - @Override - public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) { - int attatchedChlidCount = parent.getChildCount(); - int halfHeight = mAccessoryPadding / 2; - for (int i = 0; i < attatchedChlidCount - 1; ++i) { - View currentView = parent.getChildAt(i); - if (currentView.getId() == R.id.footer_command) break; - - View nextView = parent.getChildAt(i + 1); - if (nextView.getId() != R.id.footer_command) continue; - - Drawable dividerDrawable = - HorizontalListDividerDrawable.create(nextView.getContext()); - int top = currentView.getBottom() + halfHeight; - int bottom = top + dividerDrawable.getIntrinsicHeight(); - dividerDrawable.setBounds( - parent.getLeft() + parent.getPaddingLeft(), - top, - parent.getRight() - parent.getPaddingRight(), - bottom); - - dividerDrawable.draw(canvas); - } - } - } - - FooterCommandViewHolder(ViewGroup parent) { - super(parent, R.layout.password_accessory_sheet_legacy_option); + PasswordInfoViewHolder(ViewGroup parent) { + super(parent, R.layout.keyboard_accessory_sheet_tab_password_info); } @Override - protected void bind(FooterCommand footerCommand, LinearLayout layout) { - TextView view = layout.findViewById(R.id.footer_text); - view.setText(footerCommand.getDisplayText()); - view.setContentDescription(footerCommand.getDisplayText()); - view.setOnClickListener(v -> footerCommand.execute()); - view.setClickable(true); - } - } + protected void bind(KeyboardAccessoryData.UserInfo info, PasswordAccessoryInfoView view) { + bindChipView(view.getUsername(), info.getFields().get(0), view.getContext()); + bindChipView(view.getPassword(), info.getFields().get(1), view.getContext()); - /** Holds a layout for a username and a password with a small icon. */ - static class PasswordsInfoViewHolder - extends ElementViewHolder<KeyboardAccessoryData.UserInfo, LinearLayout> { - private final int mPadding; - private final int mIconSize; + view.getTitle().setVisibility(info.isExactMatch() ? View.GONE : View.VISIBLE); + // Strip the trailing slash (for aesthetic reasons): + view.getTitle().setText(stripScheme(info.getOrigin()).replaceFirst("/$", "")); - PasswordsInfoViewHolder(ViewGroup parent) { - super(parent, R.layout.keyboard_accessory_sheet_tab_legacy_password_info); - mPadding = - itemView.getContext() - .getResources() - .getDimensionPixelSize(R.dimen.keyboard_accessory_suggestion_padding); - mIconSize = - itemView.getContext() - .getResources() - .getDimensionPixelSize(R.dimen.keyboard_accessory_suggestion_icon_size); + // Set the default icon, then try to get a better one. + mFaviconRequestOrigin = info.getOrigin(); // Save the origin for returning callback. + FaviconHelper faviconHelper = FaviconHelper.create(view.getContext()); + view.setIconForBitmap(faviconHelper.getDefaultIcon(info.getOrigin())); + faviconHelper.fetchFavicon(info.getOrigin(), d -> setIcon(view, info.getOrigin(), d)); } - @Override - protected void bind(KeyboardAccessoryData.UserInfo info, LinearLayout layout) { - TextView username = layout.findViewById(R.id.suggestion_text); - TextView password = layout.findViewById(R.id.password_text); - bindTextView(username, info.getFields().get(0)); - bindTextView(password, info.getFields().get(1)); - - // Set the default icon for username, then try to get a better one. - FaviconHelper faviconHelper = FaviconHelper.create(username.getContext()); - setIconForBitmap(username, faviconHelper.getDefaultIcon(info.getOrigin())); - faviconHelper.fetchFavicon(info.getOrigin(), icon -> setIconForBitmap(username, icon)); - - ViewCompat.setPaddingRelative(username, mPadding, 0, mPadding, 0); - // Passwords have no icon, so increase the offset. - ViewCompat.setPaddingRelative(password, 2 * mPadding + mIconSize, 0, mPadding, 0); + private void setIcon( + PasswordAccessoryInfoView view, String requestOrigin, Drawable drawable) { + // Only set the icon if the origin hasn't changed since this view last requested an + // icon. Since the Views are recycled, an old callback can target a new view. + if (requestOrigin.equals(mFaviconRequestOrigin)) view.setIconForBitmap(drawable); } - private void bindTextView(TextView text, UserInfoField field) { - text.setTransformationMethod( - field.isObfuscated() ? new PasswordTransformationMethod() : null); - // With transformation, the character set forces a LTR gravity. Therefore, invert it: - text.setGravity( - Gravity.CENTER_VERTICAL - | (isLayoutRtl() && field.isObfuscated() - ? Gravity.END - : Gravity.START)); - text.setText(field.getDisplayText()); - text.setContentDescription(field.getA11yDescription()); - text.setOnClickListener(!field.isSelectable() ? null : src -> field.triggerSelection()); - text.setClickable(true); // Ensures that "disabled" is announced. - text.setEnabled(field.isSelectable()); - text.setBackground(getBackgroundDrawable(field.isSelectable())); - } - - private @Nullable Drawable getBackgroundDrawable(boolean selectable) { - if (!selectable) return null; - TypedArray a = - itemView.getContext() - .obtainStyledAttributes(new int[] {R.attr.selectableItemBackground}); - Drawable suggestionBackground = a.getDrawable(0); - a.recycle(); - return suggestionBackground; - } - - private void setIconForBitmap(TextView text, @Nullable Drawable icon) { - if (icon != null) { - icon.setBounds(0, 0, mIconSize, mIconSize); + void bindChipView(ChipView chip, UserInfoField field, Context context) { + chip.getPrimaryTextView() + .setTransformationMethod( + field.isObfuscated() ? new PasswordTransformationMethod() : null); + chip.getPrimaryTextView().setText(field.getDisplayText()); + chip.getPrimaryTextView().setContentDescription(field.getA11yDescription()); + View.OnClickListener listener = null; + if (field.isSelectable()) { + listener = src -> field.triggerSelection(); + } else if (field.isObfuscated()) { + listener = src -> InsecureFillingDialogUtils.showWarningDialog(context); } - text.setCompoundDrawablePadding(mPadding); - text.setCompoundDrawablesRelative(icon, null, null, null); + chip.setOnClickListener(listener); + chip.setClickable(listener != null); + chip.setEnabled(listener != null); } } static void initializeView(RecyclerView view, AccessorySheetTabItemsModel model) { view.setAdapter(PasswordAccessorySheetCoordinator.createAdapter(model)); - view.addItemDecoration(new FooterCommandViewHolder.DynamicTopDivider(view.getContext())); + view.addItemDecoration(new DynamicInfoViewBottomSpacer(PasswordAccessoryInfoView.class)); } }
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java index 5bd00c2..882af81 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java
@@ -55,7 +55,7 @@ @Test @MediumTest - @Feature({"KeyboardAccessoryModern", "LTR", "UiCatalogue"}) + @Feature({"KeyboardAccessory", "LTR", "UiCatalogue"}) public void testCaptureKeyboardAccessoryV2WithPasswords() throws InterruptedException, TimeoutException { mHelper.loadTestPage(false); @@ -87,7 +87,7 @@ @Test @MediumTest - @Feature({"KeyboardAccessoryModern", "RTL", "UiCatalogue"}) + @Feature({"KeyboardAccessory", "RTL", "UiCatalogue"}) public void testCaptureKeyboardAccessoryV2WithPasswordsRTL() throws InterruptedException, TimeoutException { mHelper.loadTestPage(true);
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryTestHelper.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryTestHelper.java index 3141e9e..2a70bfd2 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryTestHelper.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryTestHelper.java
@@ -43,7 +43,7 @@ * @return True iff the bar view is visible and animations have ended. */ public static boolean accessoryViewFullyShown(Activity activity) { - KeyboardAccessoryModernView accessory = activity.findViewById(R.id.keyboard_accessory); + KeyboardAccessoryView accessory = activity.findViewById(R.id.keyboard_accessory); return accessory != null && accessory.isShown() && !accessory.hasRunningAnimation() @@ -73,7 +73,7 @@ * @return True iff the bar view is hidden and animations have ended. */ public static boolean accessoryViewFullyHidden(Activity activity) { - KeyboardAccessoryModernView accessory = activity.findViewById(R.id.keyboard_accessory); + KeyboardAccessoryView accessory = activity.findViewById(R.id.keyboard_accessory); return accessory == null || (!accessory.isShown() && !accessory.hasRunningAnimation()); } }
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewTest.java similarity index 97% rename from chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java rename to chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewTest.java index a433787..9d93a09 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewTest.java
@@ -110,12 +110,12 @@ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @SuppressWarnings("DoNotMock") // Mocks GURL -public class KeyboardAccessoryModernViewTest { +public class KeyboardAccessoryViewTest { private static final String CUSTOM_ICON_URL = "https://www.example.com/image.png"; private static final Bitmap TEST_CARD_ART_IMAGE = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888); private PropertyModel mModel; - private BlockingQueue<KeyboardAccessoryModernView> mKeyboardAccessoryView; + private BlockingQueue<KeyboardAccessoryView> mKeyboardAccessoryView; @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -236,10 +236,10 @@ .findViewById(R.id.keyboard_accessory_stub); mKeyboardAccessoryView = new ArrayBlockingQueue<>(1); - ViewProvider<KeyboardAccessoryModernView> provider = + ViewProvider<KeyboardAccessoryView> provider = AsyncViewProvider.of(viewStub, R.id.keyboard_accessory); LazyConstructionPropertyMcp.create( - mModel, VISIBLE, provider, KeyboardAccessoryModernViewBinder::bind); + mModel, VISIBLE, provider, KeyboardAccessoryViewBinder::bind); provider.whenLoaded(mKeyboardAccessoryView::add); }); } @@ -255,7 +255,7 @@ () -> { mModel.set(VISIBLE, true); }); - KeyboardAccessoryModernView view = mKeyboardAccessoryView.take(); + KeyboardAccessoryView view = mKeyboardAccessoryView.take(); assertEquals(view.getVisibility(), View.VISIBLE); // After hiding the view, the view should still exist but be invisible. @@ -391,7 +391,7 @@ mModel.set(VISIBLE, true); mModel.get(BAR_ITEMS).set(createAutofillChipAndTab("John", null)); }); - KeyboardAccessoryModernView view = mKeyboardAccessoryView.take(); + KeyboardAccessoryView view = mKeyboardAccessoryView.take(); CriteriaHelper.pollUiThread( () -> view.mBarItemsView.isShown() && view.mBarItemsView.getChildAt(1) != null); CriteriaHelper.pollUiThread(viewsAreRightAligned(view, view.mBarItemsView.getChildAt(1))); @@ -592,7 +592,7 @@ mModel.set(VISIBLE, true); mModel.get(BAR_ITEMS).set(createAutofillChipAndTab("John", null)); }); - KeyboardAccessoryModernView view = mKeyboardAccessoryView.take(); + KeyboardAccessoryView view = mKeyboardAccessoryView.take(); CriteriaHelper.pollUiThread(() -> view.mBarItemsView.getChildCount() > 0); assertThat(obfuscatedChildAt.get(), is(-1)); @@ -641,7 +641,7 @@ mModel.set(VISIBLE, true); mModel.get(BAR_ITEMS).set(new BarItem[] {customIconItem, createSheetOpener()}); }); - KeyboardAccessoryModernView view = mKeyboardAccessoryView.take(); + KeyboardAccessoryView view = mKeyboardAccessoryView.take(); CriteriaHelper.pollUiThread(() -> view.mBarItemsView.getChildCount() > 0); CriteriaHelper.pollUiThread( @@ -677,7 +677,7 @@ mModel.set(VISIBLE, true); mModel.get(BAR_ITEMS).set(new BarItem[] {customIconItem, createSheetOpener()}); }); - KeyboardAccessoryModernView view = mKeyboardAccessoryView.take(); + KeyboardAccessoryView view = mKeyboardAccessoryView.take(); CriteriaHelper.pollUiThread(() -> view.mBarItemsView.getChildCount() > 0); CriteriaHelper.pollUiThread( @@ -705,7 +705,7 @@ mModel.get(BAR_ITEMS) .set(new BarItem[] {itemWithoutCustomIconUrl, createSheetOpener()}); }); - KeyboardAccessoryModernView view = mKeyboardAccessoryView.take(); + KeyboardAccessoryView view = mKeyboardAccessoryView.take(); CriteriaHelper.pollUiThread(() -> view.mBarItemsView.getChildCount() > 0); CriteriaHelper.pollUiThread(
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java deleted file mode 100644 index 3a232fc..0000000 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java +++ /dev/null
@@ -1,403 +0,0 @@ -// Copyright 2018 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.keyboard_accessory.sheet_tabs; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.RootMatchers.isDialog; -import static androidx.test.espresso.matcher.ViewMatchers.assertThat; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.text.method.PasswordTransformationMethod; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.StringRes; -import androidx.appcompat.widget.SwitchCompat; -import androidx.recyclerview.widget.RecyclerView; -import androidx.test.filters.MediumTest; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Criteria; -import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.keyboard_accessory.AccessoryAction; -import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType; -import org.chromium.chrome.browser.keyboard_accessory.R; -import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; -import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.OptionToggle; -import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.PasskeySection; -import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; -import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; -import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; -import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabItemsModel.AccessorySheetDataPiece; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.components.browser_ui.widget.chips.ChipView; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicReference; - -/** View tests for the password accessory sheet. */ -@RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -public class PasswordAccessorySheetModernViewTest { - private AccessorySheetTabItemsModel mModel; - private AtomicReference<RecyclerView> mView = new AtomicReference<>(); - - @Rule - public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); - - @Before - public void setUp() throws InterruptedException { - mActivityTestRule.startMainActivityOnBlankPage(); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - mModel = new AccessorySheetTabItemsModel(); - - AccessorySheetCoordinator accessorySheet = - new AccessorySheetCoordinator( - mActivityTestRule - .getActivity() - .findViewById(R.id.keyboard_accessory_sheet_stub), - null); - accessorySheet.setTabs( - new KeyboardAccessoryData.Tab[] { - new KeyboardAccessoryData.Tab( - "Passwords", - null, - null, - R.layout.password_accessory_sheet, - AccessoryTabType.ALL, - new KeyboardAccessoryData.Tab.Listener() { - @Override - public void onTabCreated(ViewGroup view) { - mView.set((RecyclerView) view); - AccessorySheetTabViewBinder.initializeView( - mView.get(), null); - PasswordAccessorySheetModernViewBinder - .initializeView(mView.get(), mModel); - } - - @Override - public void onTabShown() {} - }) - }); - accessorySheet.setHeight( - mActivityTestRule - .getActivity() - .getResources() - .getDimensionPixelSize( - R.dimen.keyboard_accessory_sheet_height)); - accessorySheet.show(); - }); - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get(), notNullValue())); - } - - @After - public void tearDown() { - mView.set(null); - } - - @Test - @MediumTest - public void testAddingCaptionsToTheModelRendersThem() { - assertThat(mView.get().getChildCount(), is(0)); - - TestThreadUtils.runOnUiThreadBlocking( - () -> { - mModel.add( - new AccessorySheetDataPiece( - "Passwords", AccessorySheetDataPiece.Type.TITLE)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - View title = mView.get().findViewById(R.id.tab_title); - assertThat(title, is(not(nullValue()))); - assertThat(title, instanceOf(TextView.class)); - assertThat(((TextView) title).getText(), is("Passwords")); - } - - @Test - @MediumTest - public void testAddingUserInfoToTheModelRendersClickableActions() throws ExecutionException { - final AtomicReference<Boolean> clicked = new AtomicReference<>(false); - assertThat(mView.get().getChildCount(), is(0)); - - UserInfo testInfo = new UserInfo("", false); - testInfo.addField( - new UserInfoField( - "Name Suggestion", - "Name Suggestion", - "", - false, - item -> clicked.set(true))); - testInfo.addField( - new UserInfoField( - "Password Suggestion", - "Password Suggestion", - "", - true, - item -> clicked.set(true))); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - mModel.add( - new AccessorySheetDataPiece( - testInfo, AccessorySheetDataPiece.Type.PASSWORD_INFO)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - - assertThat(getNameSuggestion().getPrimaryTextView().getText(), is("Name Suggestion")); - assertThat( - getPasswordSuggestion().getPrimaryTextView().getText(), is("Password Suggestion")); - assertThat( - getPasswordSuggestion().getPrimaryTextView().getTransformationMethod(), - instanceOf(PasswordTransformationMethod.class)); - - TestThreadUtils.runOnUiThreadBlocking(getNameSuggestion()::performClick); - assertThat(clicked.get(), is(true)); - clicked.set(false); - TestThreadUtils.runOnUiThreadBlocking(getPasswordSuggestion()::performClick); - assertThat(clicked.get(), is(true)); - } - - @Test - @MediumTest - public void testAddingPasskeySectionToTheModelRendersClickableActions() - throws ExecutionException { - final AtomicReference<Boolean> clicked = new AtomicReference<>(false); - assertThat(mView.get().getChildCount(), is(0)); - - final PasskeySection kTestPasskey = - new PasskeySection("Passkey User", () -> clicked.set(true)); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - mModel.add( - new AccessorySheetDataPiece( - kTestPasskey, AccessorySheetDataPiece.Type.PASSKEY_SECTION)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - - assertThat( - getPasskeyChipAt(0).getPrimaryTextView().getText(), - is(kTestPasskey.getDisplayName())); - assertThat( - getPasskeyChipAt(0).getSecondaryTextView().getText(), - is(getString(R.string.password_accessory_passkey_label))); - - TestThreadUtils.runOnUiThreadBlocking(getPasskeyChipAt(0)::performClick); - assertThat(clicked.get(), is(true)); - } - - @Test - @MediumTest - public void testAddingUserInfoWithObfuscatedTextAndNullCallbackRendersDialog() - throws ExecutionException { - final AtomicReference<Boolean> clicked = new AtomicReference<>(false); - assertThat(mView.get().getChildCount(), is(0)); - - UserInfo usernameEnabled = new UserInfo("", false); - usernameEnabled.addField( - new UserInfoField("username1", "username1", "", false, item -> clicked.set(true))); - usernameEnabled.addField( - new UserInfoField("pa55w0rd", "Password for username1", "", true, null)); - - TestThreadUtils.runOnUiThreadBlocking( - () -> { - mModel.add( - new AccessorySheetDataPiece( - usernameEnabled, AccessorySheetDataPiece.Type.PASSWORD_INFO)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - - assertThat(getNameSuggestion().getPrimaryTextView().getText(), is("username1")); - assertThat(getPasswordSuggestion().getPrimaryTextView().getText(), is("pa55w0rd")); - assertThat( - getPasswordSuggestion().getPrimaryTextView().getTransformationMethod(), - instanceOf(PasswordTransformationMethod.class)); - - TestThreadUtils.runOnUiThreadBlocking(getNameSuggestion()::performClick); - assertThat(clicked.get(), is(true)); - TestThreadUtils.runOnUiThreadBlocking(getPasswordSuggestion()::performClick); - assertInsecureFillingDialog(); - } - - @Test - @MediumTest - public void testAddingUserInfoTitlesAreRenderedIfNotEmpty() { - assertThat(mView.get().getChildCount(), is(0)); - final UserInfoField kUnusedInfoField = - new UserInfoField("Unused Name", "Unused Password", "", false, cb -> {}); - - TestThreadUtils.runOnUiThreadBlocking( - () -> { - UserInfo sameOriginInfo = new UserInfo("", true); - sameOriginInfo.addField(kUnusedInfoField); - sameOriginInfo.addField(kUnusedInfoField); - mModel.add( - new AccessorySheetDataPiece( - sameOriginInfo, AccessorySheetDataPiece.Type.PASSWORD_INFO)); - - UserInfo pslOriginInfo = new UserInfo("other.origin.eg", false); - pslOriginInfo.addField(kUnusedInfoField); - pslOriginInfo.addField(kUnusedInfoField); - mModel.add( - new AccessorySheetDataPiece( - pslOriginInfo, AccessorySheetDataPiece.Type.PASSWORD_INFO)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(2))); - - assertThat(getUserInfoAt(0).getTitle().isShown(), is(false)); - assertThat(getUserInfoAt(1).getTitle().isShown(), is(true)); - assertThat(getUserInfoAt(1).getTitle().getText(), is("other.origin.eg")); - } - - @Test - @MediumTest - public void testOptionToggleRenderedIfNotEmpty() throws ExecutionException { - assertThat(mView.get().getChildCount(), is(0)); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - OptionToggle toggle = - new OptionToggle( - "Save passwords for this site", - false, - AccessoryAction.TOGGLE_SAVE_PASSWORDS, - result -> {}); - mModel.add( - new AccessorySheetDataPiece( - toggle, AccessorySheetDataPiece.Type.OPTION_TOGGLE)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - View title = mView.get().findViewById(R.id.option_toggle_title); - assertThat(title, is(not(nullValue()))); - assertThat(title, instanceOf(TextView.class)); - assertThat(((TextView) title).getText(), is("Save passwords for this site")); - - View subtitle = mView.get().findViewById(R.id.option_toggle_subtitle); - assertThat(subtitle, is(not(nullValue()))); - assertThat(subtitle, instanceOf(TextView.class)); - assertThat(subtitle, withText(R.string.text_off)); - - View switchView = mView.get().findViewById(R.id.option_toggle_switch); - assertThat(switchView, is(not(nullValue()))); - assertThat(switchView, instanceOf(SwitchCompat.class)); - assertFalse(((SwitchCompat) switchView).isChecked()); - } - - @Test - @MediumTest - public void testClickingDisabledToggleInvokesCallbackToEnable() throws ExecutionException { - AtomicReference<Boolean> toggleEnabled = new AtomicReference<>(); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - OptionToggle toggle = - new OptionToggle( - "Save passwords for this site", - false, - AccessoryAction.TOGGLE_SAVE_PASSWORDS, - toggleEnabled::set); - mModel.add( - new AccessorySheetDataPiece( - toggle, AccessorySheetDataPiece.Type.OPTION_TOGGLE)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - TestThreadUtils.runOnUiThreadBlocking( - mView.get().findViewById(R.id.option_toggle)::performClick); - assertTrue(toggleEnabled.get()); - } - - @Test - @MediumTest - public void testClickingEnabledToggleInvokesCallbackToDisable() throws ExecutionException { - AtomicReference<Boolean> toggleEnabled = new AtomicReference<>(); - TestThreadUtils.runOnUiThreadBlocking( - () -> { - OptionToggle toggle = - new OptionToggle( - "Save passwords for this site", - true, - AccessoryAction.TOGGLE_SAVE_PASSWORDS, - toggleEnabled::set); - mModel.add( - new AccessorySheetDataPiece( - toggle, AccessorySheetDataPiece.Type.OPTION_TOGGLE)); - }); - - CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - TestThreadUtils.runOnUiThreadBlocking( - mView.get().findViewById(R.id.option_toggle)::performClick); - - assertFalse(toggleEnabled.get()); - } - - private String getString(@StringRes int strId) { - return mView.get().getResources().getString(strId); - } - - private ChipView getPasskeyChipAt(int index) { - assertThat(mView.get().getChildCount(), is(greaterThan(index))); - assertThat(mView.get().getChildAt(index), instanceOf(ViewGroup.class)); - LinearLayout passkeySection = (LinearLayout) mView.get().getChildAt(index); - return passkeySection.findViewById(R.id.keyboard_accessory_sheet_chip); - } - - private PasswordAccessoryInfoView getUserInfoAt(int index) { - assertThat(mView.get().getChildCount(), is(greaterThan(index))); - assertThat(mView.get().getChildAt(index), instanceOf(PasswordAccessoryInfoView.class)); - return (PasswordAccessoryInfoView) mView.get().getChildAt(index); - } - - private ChipView getNameSuggestion() { - View view = getUserInfoAt(0).findViewById(R.id.suggestion_text); - assertThat(view, is(not(nullValue()))); - assertThat(view, instanceOf(ChipView.class)); - return (ChipView) view; - } - - private ChipView getPasswordSuggestion() { - View view = getUserInfoAt(0).findViewById(R.id.password_text); - assertThat(view, is(not(nullValue()))); - assertThat(view, instanceOf(ChipView.class)); - return (ChipView) view; - } - - private void assertInsecureFillingDialog() { - CriteriaHelper.pollInstrumentationThread( - () -> { - onView(withText(R.string.passwords_not_secure_filling)) - .inRoot(isDialog()) - .check(matches(isDisplayed())); - onView(withText(R.string.passwords_not_secure_filling_details)) - .inRoot(isDialog()) - .check(matches(isDisplayed())); - }); - } -}
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java index eda5ff84..e605c0f 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java
@@ -4,13 +4,21 @@ package org.chromium.chrome.browser.keyboard_accessory.sheet_tabs; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.assertThat; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import android.text.method.PasswordTransformationMethod; import android.view.View; @@ -18,7 +26,8 @@ import android.widget.LinearLayout; import android.widget.TextView; -import androidx.annotation.LayoutRes; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.SwitchCompat; import androidx.recyclerview.widget.RecyclerView; import androidx.test.filters.MediumTest; @@ -32,15 +41,19 @@ import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.keyboard_accessory.AccessoryAction; import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType; import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; +import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.OptionToggle; +import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.PasskeySection; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabItemsModel.AccessorySheetDataPiece; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.components.browser_ui.widget.chips.ChipView; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.util.concurrent.ExecutionException; @@ -56,18 +69,13 @@ @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); - /** - * This helper method inflates the accessory sheet and loads the given layout as minimalistic - * Tab. The passed callback then allows access to the inflated layout. - * - * @param layout The layout to be inflated. - * @param listener Is called with the inflated layout when the Accessory Sheet initializes it. - */ - private void openLayoutInAccessorySheet( - @LayoutRes int layout, KeyboardAccessoryData.Tab.Listener listener) { + @Before + public void setUp() throws InterruptedException { + mActivityTestRule.startMainActivityOnBlankPage(); TestThreadUtils.runOnUiThreadBlocking( () -> { mModel = new AccessorySheetTabItemsModel(); + AccessorySheetCoordinator accessorySheet = new AccessorySheetCoordinator( mActivityTestRule @@ -80,9 +88,21 @@ "Passwords", null, null, - layout, + R.layout.password_accessory_sheet, AccessoryTabType.ALL, - listener) + new KeyboardAccessoryData.Tab.Listener() { + @Override + public void onTabCreated(ViewGroup view) { + mView.set((RecyclerView) view); + AccessorySheetTabViewBinder.initializeView( + mView.get(), null); + PasswordAccessorySheetViewBinder + .initializeView(mView.get(), mModel); + } + + @Override + public void onTabShown() {} + }) }); accessorySheet.setHeight( mActivityTestRule @@ -92,26 +112,6 @@ R.dimen.keyboard_accessory_sheet_height)); accessorySheet.show(); }); - } - - @Before - public void setUp() throws InterruptedException { - mActivityTestRule.startMainActivityOnBlankPage(); - openLayoutInAccessorySheet( - R.layout.password_accessory_sheet, - new KeyboardAccessoryData.Tab.Listener() { - @Override - public void onTabCreated(ViewGroup view) { - mView.set((RecyclerView) view); - // Reuse coordinator code to create and wire the adapter. No mediator - // involved. - AccessorySheetTabViewBinder.initializeView(mView.get(), null); - PasswordAccessorySheetViewBinder.initializeView(mView.get(), mModel); - } - - @Override - public void onTabShown() {} - }); CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get(), notNullValue())); } @@ -169,10 +169,11 @@ CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); - assertThat(getNameSuggestion().getText(), is("Name Suggestion")); - assertThat(getPasswordSuggestion().getText(), is("Password Suggestion")); + assertThat(getNameSuggestion().getPrimaryTextView().getText(), is("Name Suggestion")); assertThat( - getPasswordSuggestion().getTransformationMethod(), + getPasswordSuggestion().getPrimaryTextView().getText(), is("Password Suggestion")); + assertThat( + getPasswordSuggestion().getPrimaryTextView().getTransformationMethod(), instanceOf(PasswordTransformationMethod.class)); TestThreadUtils.runOnUiThreadBlocking(getNameSuggestion()::performClick); @@ -182,21 +183,221 @@ assertThat(clicked.get(), is(true)); } - private TextView getNameSuggestion() { - assertThat(mView.get().getChildAt(0), instanceOf(LinearLayout.class)); - LinearLayout layout = (LinearLayout) mView.get().getChildAt(0); - View view = layout.findViewById(R.id.suggestion_text); - assertThat(view, is(not(nullValue()))); - assertThat(view, instanceOf(TextView.class)); - return (TextView) view; + @Test + @MediumTest + public void testAddingPasskeySectionToTheModelRendersClickableActions() + throws ExecutionException { + final AtomicReference<Boolean> clicked = new AtomicReference<>(false); + assertThat(mView.get().getChildCount(), is(0)); + + final PasskeySection kTestPasskey = + new PasskeySection("Passkey User", () -> clicked.set(true)); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + mModel.add( + new AccessorySheetDataPiece( + kTestPasskey, AccessorySheetDataPiece.Type.PASSKEY_SECTION)); + }); + + CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); + + assertThat( + getPasskeyChipAt(0).getPrimaryTextView().getText(), + is(kTestPasskey.getDisplayName())); + assertThat( + getPasskeyChipAt(0).getSecondaryTextView().getText(), + is(getString(R.string.password_accessory_passkey_label))); + + TestThreadUtils.runOnUiThreadBlocking(getPasskeyChipAt(0)::performClick); + assertThat(clicked.get(), is(true)); } - private TextView getPasswordSuggestion() { - assertThat(mView.get().getChildAt(0), instanceOf(LinearLayout.class)); - LinearLayout layout = (LinearLayout) mView.get().getChildAt(0); - View view = layout.findViewById(R.id.password_text); + @Test + @MediumTest + public void testAddingUserInfoWithObfuscatedTextAndNullCallbackRendersDialog() + throws ExecutionException { + final AtomicReference<Boolean> clicked = new AtomicReference<>(false); + assertThat(mView.get().getChildCount(), is(0)); + + UserInfo usernameEnabled = new UserInfo("", false); + usernameEnabled.addField( + new UserInfoField("username1", "username1", "", false, item -> clicked.set(true))); + usernameEnabled.addField( + new UserInfoField("pa55w0rd", "Password for username1", "", true, null)); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { + mModel.add( + new AccessorySheetDataPiece( + usernameEnabled, AccessorySheetDataPiece.Type.PASSWORD_INFO)); + }); + + CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); + + assertThat(getNameSuggestion().getPrimaryTextView().getText(), is("username1")); + assertThat(getPasswordSuggestion().getPrimaryTextView().getText(), is("pa55w0rd")); + assertThat( + getPasswordSuggestion().getPrimaryTextView().getTransformationMethod(), + instanceOf(PasswordTransformationMethod.class)); + + TestThreadUtils.runOnUiThreadBlocking(getNameSuggestion()::performClick); + assertThat(clicked.get(), is(true)); + TestThreadUtils.runOnUiThreadBlocking(getPasswordSuggestion()::performClick); + assertInsecureFillingDialog(); + } + + @Test + @MediumTest + public void testAddingUserInfoTitlesAreRenderedIfNotEmpty() { + assertThat(mView.get().getChildCount(), is(0)); + final UserInfoField kUnusedInfoField = + new UserInfoField("Unused Name", "Unused Password", "", false, cb -> {}); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { + UserInfo sameOriginInfo = new UserInfo("", true); + sameOriginInfo.addField(kUnusedInfoField); + sameOriginInfo.addField(kUnusedInfoField); + mModel.add( + new AccessorySheetDataPiece( + sameOriginInfo, AccessorySheetDataPiece.Type.PASSWORD_INFO)); + + UserInfo pslOriginInfo = new UserInfo("other.origin.eg", false); + pslOriginInfo.addField(kUnusedInfoField); + pslOriginInfo.addField(kUnusedInfoField); + mModel.add( + new AccessorySheetDataPiece( + pslOriginInfo, AccessorySheetDataPiece.Type.PASSWORD_INFO)); + }); + + CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(2))); + + assertThat(getUserInfoAt(0).getTitle().isShown(), is(false)); + assertThat(getUserInfoAt(1).getTitle().isShown(), is(true)); + assertThat(getUserInfoAt(1).getTitle().getText(), is("other.origin.eg")); + } + + @Test + @MediumTest + public void testOptionToggleRenderedIfNotEmpty() throws ExecutionException { + assertThat(mView.get().getChildCount(), is(0)); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + OptionToggle toggle = + new OptionToggle( + "Save passwords for this site", + false, + AccessoryAction.TOGGLE_SAVE_PASSWORDS, + result -> {}); + mModel.add( + new AccessorySheetDataPiece( + toggle, AccessorySheetDataPiece.Type.OPTION_TOGGLE)); + }); + + CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); + View title = mView.get().findViewById(R.id.option_toggle_title); + assertThat(title, is(not(nullValue()))); + assertThat(title, instanceOf(TextView.class)); + assertThat(((TextView) title).getText(), is("Save passwords for this site")); + + View subtitle = mView.get().findViewById(R.id.option_toggle_subtitle); + assertThat(subtitle, is(not(nullValue()))); + assertThat(subtitle, instanceOf(TextView.class)); + assertThat(subtitle, withText(R.string.text_off)); + + View switchView = mView.get().findViewById(R.id.option_toggle_switch); + assertThat(switchView, is(not(nullValue()))); + assertThat(switchView, instanceOf(SwitchCompat.class)); + assertFalse(((SwitchCompat) switchView).isChecked()); + } + + @Test + @MediumTest + public void testClickingDisabledToggleInvokesCallbackToEnable() throws ExecutionException { + AtomicReference<Boolean> toggleEnabled = new AtomicReference<>(); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + OptionToggle toggle = + new OptionToggle( + "Save passwords for this site", + false, + AccessoryAction.TOGGLE_SAVE_PASSWORDS, + toggleEnabled::set); + mModel.add( + new AccessorySheetDataPiece( + toggle, AccessorySheetDataPiece.Type.OPTION_TOGGLE)); + }); + + CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); + TestThreadUtils.runOnUiThreadBlocking( + mView.get().findViewById(R.id.option_toggle)::performClick); + assertTrue(toggleEnabled.get()); + } + + @Test + @MediumTest + public void testClickingEnabledToggleInvokesCallbackToDisable() throws ExecutionException { + AtomicReference<Boolean> toggleEnabled = new AtomicReference<>(); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + OptionToggle toggle = + new OptionToggle( + "Save passwords for this site", + true, + AccessoryAction.TOGGLE_SAVE_PASSWORDS, + toggleEnabled::set); + mModel.add( + new AccessorySheetDataPiece( + toggle, AccessorySheetDataPiece.Type.OPTION_TOGGLE)); + }); + + CriteriaHelper.pollUiThread(() -> Criteria.checkThat(mView.get().getChildCount(), is(1))); + TestThreadUtils.runOnUiThreadBlocking( + mView.get().findViewById(R.id.option_toggle)::performClick); + + assertFalse(toggleEnabled.get()); + } + + private String getString(@StringRes int strId) { + return mView.get().getResources().getString(strId); + } + + private ChipView getPasskeyChipAt(int index) { + assertThat(mView.get().getChildCount(), is(greaterThan(index))); + assertThat(mView.get().getChildAt(index), instanceOf(ViewGroup.class)); + LinearLayout passkeySection = (LinearLayout) mView.get().getChildAt(index); + return passkeySection.findViewById(R.id.keyboard_accessory_sheet_chip); + } + + private PasswordAccessoryInfoView getUserInfoAt(int index) { + assertThat(mView.get().getChildCount(), is(greaterThan(index))); + assertThat(mView.get().getChildAt(index), instanceOf(PasswordAccessoryInfoView.class)); + return (PasswordAccessoryInfoView) mView.get().getChildAt(index); + } + + private ChipView getNameSuggestion() { + View view = getUserInfoAt(0).findViewById(R.id.suggestion_text); assertThat(view, is(not(nullValue()))); - assertThat(view, instanceOf(TextView.class)); - return (TextView) view; + assertThat(view, instanceOf(ChipView.class)); + return (ChipView) view; + } + + private ChipView getPasswordSuggestion() { + View view = getUserInfoAt(0).findViewById(R.id.password_text); + assertThat(view, is(not(nullValue()))); + assertThat(view, instanceOf(ChipView.class)); + return (ChipView) view; + } + + private void assertInsecureFillingDialog() { + CriteriaHelper.pollInstrumentationThread( + () -> { + onView(withText(R.string.passwords_not_secure_filling)) + .inRoot(isDialog()) + .check(matches(isDisplayed())); + onView(withText(R.string.passwords_not_secure_filling_details)) + .inRoot(isDialog()) + .check(matches(isDisplayed())); + }); } }
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java index b9afefa..85ca741 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
@@ -70,7 +70,7 @@ @Mock private ListObservable.ListObserver<Void> mMockActionListObserver; @Mock private KeyboardAccessoryCoordinator.BarVisibilityDelegate mMockBarVisibilityDelegate; @Mock private AccessorySheetCoordinator.SheetVisibilityDelegate mMockSheetVisibilityDelegate; - @Mock private KeyboardAccessoryModernView mMockView; + @Mock private KeyboardAccessoryView mMockView; @Mock private KeyboardAccessoryButtonGroupCoordinator mMockButtonGroup; @Mock private KeyboardAccessoryCoordinator.TabSwitchingDelegate mMockTabSwitchingDelegate; @Mock private AutofillDelegate mMockAutofillDelegate; @@ -560,7 +560,7 @@ } @Test - public void testModelChangesUpdatesTheContentDescriptionInModernView() { + public void testModelChangesUpdatesTheContentDescription() { PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider = new PropertyProvider<>(AUTOFILL_SUGGESTION);
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java index e6e53080..9e2e1637 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java
@@ -150,7 +150,7 @@ } @Test - public void testUsesTabTitleOnlyForEmptyListsForModernDesign() { + public void testUsesTabTitleOnlyForEmptyLists() { final PropertyProvider<AccessorySheetData> testProvider = new PropertyProvider<>(); final AccessorySheetData testData = new AccessorySheetData(AccessoryTabType.PASSWORDS, "No passwords for this", "");
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java index 0199806..70fd243 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java
@@ -120,8 +120,8 @@ /** * @return Whether the Start Surface feature flag is enabled. - * @Deprecated Use {@link - * org.chromium.chrome.browser.tasks.ReturnToChromeUtil#isStartSurfaceEnabled} instead. + * @deprecated Use {@link + * org.chromium.chrome.browser.tasks.ReturnToChromeUtil#isStartSurfaceEnabled} instead. */ public static boolean isStartSurfaceFlagEnabled() { return ChromeFeatureList.sStartSurfaceAndroid.isEnabled() && !SysUtils.isLowEndDevice();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java index 39b044db..13fc263 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ActivityTabProvider.java
@@ -54,10 +54,11 @@ * A notification that the observer has switched to observing a different tab. This can be * called a first time with the {@code hint} parameter set to true, indicating that a new * tab is going to be selected. + * * @param tab The tab that the observer is now observing. This can be null. * @param hint Whether the change event is a hint that a tab change is likely. If true, the - * provided tab may still be frozen and is not yet selected. - * @Deprecated - hint is unused, override this method without the hint parameter. + * provided tab may still be frozen and is not yet selected. + * @deprecated - hint is unused, override this method without the hint parameter. */ protected void onObservingDifferentTab(Tab tab, boolean hint) {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index 39988c451..5cae320a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -2052,8 +2052,9 @@ /** * Gets the {@link TabContentManager} instance which holds snapshots of the tabs in this model. + * * @return The thumbnail cache, possibly null. - * @Deprecated in favor of getTabContentManagerSupplier(). + * @deprecated in favor of getTabContentManagerSupplier(). */ @Deprecated public TabContentManager getTabContentManager() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java index 54ab609..902ced8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java
@@ -392,7 +392,7 @@ } /** - * @Return Whether the button is hovered on. + * @return Whether the button is hovered on. */ public boolean isHovered() { return mIsHovered; @@ -408,14 +408,14 @@ } /** - * @Return Whether the button is pressed from mouse. + * @return Whether the button is pressed from mouse. */ public boolean isPressedFromMouse() { return mIsPressed && mIsPressedFromMouse; } /** - * @Return Whether hover background should be applied to the button. + * @return Whether hover background should be applied to the button. */ public boolean getShouldApplyHoverBackground() { return isHovered() || isPressedFromMouse();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java index d15a8fec..6b95ba9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -601,8 +601,8 @@ } /** - * @Return The start padding needed for model selector button to ensure there is enough space - * for touch target. + * @return The start padding needed for model selector button to ensure there is enough space + * for touch target. */ private float getButtonStartPaddingForTouchTarget() { if (mModelSelectorButton.isVisible()) {
diff --git a/chrome/browser/accessibility/media_app/ax_media_app_untrusted_handler_unittest.cc b/chrome/browser/accessibility/media_app/ax_media_app_untrusted_handler_unittest.cc index ac24fb612..ecb1f4d2 100644 --- a/chrome/browser/accessibility/media_app/ax_media_app_untrusted_handler_unittest.cc +++ b/chrome/browser/accessibility/media_app/ax_media_app_untrusted_handler_unittest.cc
@@ -97,12 +97,12 @@ EXPECT_FALSE(handler_->IsOcrServiceEnabled()); EXPECT_FALSE(fake_media_app_.IsOcrServiceEnabled()); - screen_ai::ScreenAIInstallState::GetInstance()->SetState( + screen_ai::ScreenAIInstallState::GetInstance()->SetStateForTesting( screen_ai::ScreenAIInstallState::State::kReady); EXPECT_TRUE(handler_->IsOcrServiceEnabled()); EXPECT_TRUE(fake_media_app_.IsOcrServiceEnabled()); - screen_ai::ScreenAIInstallState::GetInstance()->SetState( + screen_ai::ScreenAIInstallState::GetInstance()->SetStateForTesting( screen_ai::ScreenAIInstallState::State::kNotDownloaded); EXPECT_FALSE(handler_->IsOcrServiceEnabled()); EXPECT_FALSE(fake_media_app_.IsOcrServiceEnabled());
diff --git a/chrome/browser/accessibility/pdf_ocr_controller.cc b/chrome/browser/accessibility/pdf_ocr_controller.cc index e5a6d4c8..0847ad1 100644 --- a/chrome/browser/accessibility/pdf_ocr_controller.cc +++ b/chrome/browser/accessibility/pdf_ocr_controller.cc
@@ -197,6 +197,11 @@ } void PdfOcrController::SendPdfOcrAlwaysActiveToAll(bool is_always_active) { + if (is_always_active) { + CHECK_EQ(ScreenAIInstallState::GetInstance()->get_state(), + ScreenAIInstallState::State::kReady); + } + std::vector<content::WebContents*> html_web_contents_vector = GetPdfHtmlWebContentses(profile_); // Iterate over all WebContentses associated with PDF Viewer Mimehandlers and
diff --git a/chrome/browser/apps/app_service/app_install/app_install_service_ash.cc b/chrome/browser/apps/app_service/app_install/app_install_service_ash.cc index 6ba45d6..e9ab5c1 100644 --- a/chrome/browser/apps/app_service/app_install/app_install_service_ash.cc +++ b/chrome/browser/apps/app_service/app_install/app_install_service_ash.cc
@@ -155,7 +155,7 @@ base::BindOnce( [](base::WeakPtr<ash::app_install::AppInstallDialog> dialog, bool dialog_accepted) { - dialog->SetInstallSuccess(true); + dialog->SetInstallComplete(nullptr); }, dialog)); return AppInstallResult::kUnknown;
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc index ff9d301..383ac05 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -243,8 +243,11 @@ ->GetMediaStreamCaptureIndicator() .get()); - notification_display_service_.Observe( - NotificationDisplayServiceFactory::GetForProfile(profile())); + // NotificationDisplayService could be null in some tests. + if (auto* notification_display_service = + NotificationDisplayServiceFactory::GetForProfile(profile())) { + notification_display_service_.Observe(notification_display_service); + } profile_pref_change_registrar_.Init(profile()->GetPrefs()); profile_pref_change_registrar_.Add(
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index d39645b..6cf1a9b 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -5144,6 +5144,7 @@ "app_list/search/test/test_search_provider.h", "app_list/search/util/ftrl_optimizer_unittest.cc", "app_list/search/util/keyword_cache_unittest.cc", + "app_list/search/util/manatee_unittest.cc", "app_list/search/util/mrfu_cache_unittest.cc", "app_list/search/util/persistent_proto_unittest.cc", "app_list/search/util/score_normalizer_unittest.cc",
diff --git a/chrome/browser/ash/app_list/search/util/manatee.cc b/chrome/browser/ash/app_list/search/util/manatee.cc new file mode 100644 index 0000000..4ca4572 --- /dev/null +++ b/chrome/browser/ash/app_list/search/util/manatee.cc
@@ -0,0 +1,21 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/app_list/search/util/manatee.h" + +#include <numeric> +#include <optional> +#include <vector> + +namespace app_list { + +std::optional<double> GetWordSimilarity(const std::vector<double>& vector1, + const std::vector<double>& vector2) { + if (vector1.size() != vector2.size()) { + return std::nullopt; + } + return std::inner_product(vector1.begin(), vector1.end(), vector2.begin(), 0); +} + +} // namespace app_list
diff --git a/chrome/browser/ash/app_list/search/util/manatee.h b/chrome/browser/ash/app_list/search/util/manatee.h new file mode 100644 index 0000000..bbc4095 --- /dev/null +++ b/chrome/browser/ash/app_list/search/util/manatee.h
@@ -0,0 +1,18 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_APP_LIST_SEARCH_UTIL_MANATEE_H_ +#define CHROME_BROWSER_ASH_APP_LIST_SEARCH_UTIL_MANATEE_H_ + +#include <optional> +#include <vector> + +namespace app_list { + +std::optional<double> GetWordSimilarity(const std::vector<double>& vector1, + const std::vector<double>& vector2); + +} // namespace app_list + +#endif // CHROME_BROWSER_ASH_APP_LIST_SEARCH_MANATEE_H_
diff --git a/chrome/browser/ash/app_list/search/util/manatee_unittest.cc b/chrome/browser/ash/app_list/search/util/manatee_unittest.cc new file mode 100644 index 0000000..4f502b4 --- /dev/null +++ b/chrome/browser/ash/app_list/search/util/manatee_unittest.cc
@@ -0,0 +1,56 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/app_list/search/util/manatee.h" + +#include <vector> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace app_list::test { + +TEST(ManateeTest, GetWordSimilarityPositiveVectors) { + // Test for successful dot product calculation of two + // positive input vectors + + std::vector<double> v1{1.0, 2.0, 3.0}; + std::vector<double> v2{4.0, 5.0, 6.0}; + absl::optional<double> result = GetWordSimilarity(v1, v2); + ASSERT_TRUE(result.has_value()); + EXPECT_DOUBLE_EQ(32.0, result.value()); +} + +TEST(ManateeTest, GetWordSimilarityMismatchingSize) { + // Test for correct handling of input vectors + // with mismatching size + + std::vector<double> v1{1.0, 2.0, 3.0}; + std::vector<double> v2{4.0, 5.0, 6.0, 7.0}; + absl::optional<double> result = GetWordSimilarity(v1, v2); + ASSERT_FALSE(result.has_value()); +} + +TEST(ManateeTest, GetWordSimilarityEmptyVectors) { + // Test for correct handling of empty input vectors + + std::vector<double> v1{}; + std::vector<double> v2{}; + absl::optional<double> result = GetWordSimilarity(v1, v2); + ASSERT_TRUE(result.has_value()); + EXPECT_DOUBLE_EQ(0.0, result.value()); +} + +TEST(ManateeTest, GetWordSimilarityZeroVectors) { + // Test for correct dot product with a vector of + // all zero values + + std::vector<double> v1{1.0, 2.0, 3.0}; + std::vector<double> v2{0.0, 0.0, 0.0}; + absl::optional<double> result = GetWordSimilarity(v1, v2); + ASSERT_TRUE(result.has_value()); + EXPECT_DOUBLE_EQ(0.0, result.value()); +} + +} // namespace app_list::test
diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h index 1b54105..af4f7d8 100644 --- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h +++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h
@@ -7,6 +7,7 @@ #include "ash/components/arc/mojom/app.mojom.h" #include "ash/constants/ash_features.h" +#include "base/containers/flat_map.h" #include "base/memory/raw_ptr.h" #include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h"
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.h b/chrome/browser/ash/arc/input_overlay/touch_injector.h index ade046d19..ea0915c 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.h +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.h
@@ -9,6 +9,7 @@ #include <optional> #include <vector> +#include "base/containers/flat_map.h" #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" #include "base/observer_list.h"
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc b/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc index 25200dd..0825afa 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc +++ b/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc
@@ -9,7 +9,6 @@ #include "ash/constants/ash_switches.h" #include "base/check.h" #include "base/command_line.h" -#include "base/environment.h" #include "chrome/browser/ash/crosapi/browser_manager.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/crosapi/fake_device_ownership_waiter.h" @@ -17,35 +16,21 @@ #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_types.h" #include "components/policy/policy_constants.h" -#include "testing/gtest/include/gtest/gtest.h" namespace ash { bool KioskAshBrowserTestStarter::HasLacrosArgument() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - ash::switches::kLacrosChromePath); + return ash_browser_test_starter_.HasLacrosArgument(); } void KioskAshBrowserTestStarter::PrepareEnvironmentForKioskLacros() { - DCHECK(HasLacrosArgument()); - std::unique_ptr<base::Environment> env(base::Environment::Create()); - ASSERT_TRUE(scoped_temp_dir_xdg_.CreateUniqueTempDir()); - env->SetVar("XDG_RUNTIME_DIR", scoped_temp_dir_xdg_.GetPath().AsUTF8Unsafe()); + CHECK(ash_browser_test_starter_.PrepareEnvironmentForLacros()); - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ash::switches::kAshEnableWaylandServer); - - std::vector<std::string> lacros_args = { - // Disable gpu process in Lacros since hardware accelerated rendering is - // not possible yet in Ash X11 backend. See details in crbug/1478369. - "--disable-gpu", - // Disable gpu sandbox in Lacros since it fails in Linux emulator - // environment. - // See details in crbug/1483530. - "--disable-gpu-sandbox"}; - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - ash::switches::kLacrosChromeAdditionalArgs, - base::JoinString(lacros_args, "####")); + // The `kDisableLacrosKeepAliveForTesting` switch is set by + // `AshBrowserTestStarter`, but kiosk launch relies on `KeepAlive`, so remove + // it again. + base::CommandLine::ForCurrentProcess()->RemoveSwitch( + switches::kDisableLacrosKeepAliveForTesting); } void KioskAshBrowserTestStarter::SetLacrosAvailabilityPolicy() { @@ -60,9 +45,7 @@ } void KioskAshBrowserTestStarter::SetUpBrowserManager() { - DCHECK(HasLacrosArgument()); - crosapi::BrowserManager::Get()->set_device_ownership_waiter_for_testing( - std::make_unique<crosapi::FakeDeviceOwnershipWaiter>()); + ash_browser_test_starter_.SetUpBrowserManager(); } } // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.h b/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.h index dc00718c..fdf6e32 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.h +++ b/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_ASH_BROWSER_TEST_STARTER_H_ #define CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_ASH_BROWSER_TEST_STARTER_H_ -#include "base/files/scoped_temp_dir.h" +#include "chrome/test/base/chromeos/ash_browser_test_starter.h" namespace ash { @@ -27,7 +27,7 @@ void SetUpBrowserManager(); private: - base::ScopedTempDir scoped_temp_dir_xdg_; + ::test::AshBrowserTestStarter ash_browser_test_starter_; }; } // namespace ash
diff --git a/chrome/browser/ash/login/lock/screen_locker_unittest.cc b/chrome/browser/ash/login/lock/screen_locker_unittest.cc index 69250893..8118fd6b 100644 --- a/chrome/browser/ash/login/lock/screen_locker_unittest.cc +++ b/chrome/browser/ash/login/lock/screen_locker_unittest.cc
@@ -206,11 +206,30 @@ // the device. TEST_F(ScreenLockerUnitTest, VerifyAshIsNotifiedOfScreenLocked) { CreateSessionForUser(/*is_public_account=*/false); - EXPECT_EQ(0, test_session_controller_.lock_animation_complete_call_count()); + + // Show the lock screen. ScreenLocker::Show(); base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(ScreenLocker::default_screen_locker()); + EXPECT_TRUE(ScreenLocker::default_screen_locker()->locked()); EXPECT_EQ(1, test_session_controller_.lock_animation_complete_call_count()); + + // Hide the lock screen. + ScreenLocker::Hide(); + // Needed to perform internal cleanup scheduled in ScreenLocker::Hide() + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(ScreenLocker::default_screen_locker()); +} + +// Tests that `GetUsersToShow()` returns a list with one user when the user is +// regular. +TEST_F(ScreenLockerUnitTest, GetUsersToShowRegular) { + CreateSessionForUser(/*is_public_account=*/false); + + ScreenLocker::Show(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(ScreenLocker::default_screen_locker()->GetUsersToShow().size(), 1u); ScreenLocker::Hide(); // Needed to perform internal cleanup scheduled in ScreenLocker::Hide() base::RunLoop().RunUntilIdle(); @@ -218,7 +237,7 @@ // Tests that `GetUsersToShow()` returns an empty list when the user is a // Managed Guest Session. -TEST_F(ScreenLockerUnitTest, GetUsersToShow) { +TEST_F(ScreenLockerUnitTest, GetUsersToShowPublicAccount) { CreateSessionForUser(/*is_public_account=*/true); ScreenLocker::Show();
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.cc b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.cc index 874a9a0..eb44bd6 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.cc +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.cc
@@ -29,6 +29,33 @@ namespace policy { +namespace { + +// Returns the accessible name for the learn more link of the given block +// `reason`. +std::u16string GetAccessibleLearnMoreLinkNameForBlockReason( + policy::FilesPolicyDialog::BlockReason reason) { + switch (reason) { + case FilesPolicyDialog::BlockReason::kDlp: + return l10n_util::GetStringUTF16( + IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_DATA_CONTROLS_ACCESSIBLE_NAME); + case FilesPolicyDialog::BlockReason::kEnterpriseConnectorsSensitiveData: + return l10n_util::GetStringUTF16( + IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_SENSITIVE_DATA_PROTECTION_ACCESSIBLE_NAME); + case FilesPolicyDialog::BlockReason::kEnterpriseConnectorsMalware: + return l10n_util::GetStringUTF16( + IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_MALWARE_PROTECTION_ACCESSIBLE_NAME); + case FilesPolicyDialog::BlockReason::kEnterpriseConnectorsUnknownScanResult: + case FilesPolicyDialog::BlockReason::kEnterpriseConnectorsEncryptedFile: + case FilesPolicyDialog::BlockReason::kEnterpriseConnectorsLargeFile: + case FilesPolicyDialog::BlockReason::kEnterpriseConnectors: + // Currently these block reasons cannot have a learn more link. + return std::u16string(); + } +} + +} // namespace + FilesPolicyDialogFactory* factory_; // static @@ -73,6 +100,9 @@ settings.learn_more_url_ = GURL(dlp::kDlpLearnMoreUrl); } + settings.accessible_learn_more_link_name_ = + GetAccessibleLearnMoreLinkNameForBlockReason(reason); + return settings; } @@ -94,6 +124,9 @@ settings.learn_more_url_ = GURL(dlp::kDlpLearnMoreUrl); } + settings.accessible_learn_more_link_name_ = + GetAccessibleLearnMoreLinkNameForBlockReason(reason); + return settings; } @@ -110,7 +143,9 @@ return bypass_requires_justification_ == other.bypass_requires_justification_ && message_ == other.message_ && - learn_more_url_ == other.learn_more_url_ && files_ == other.files_; + learn_more_url_ == other.learn_more_url_ && files_ == other.files_ && + accessible_learn_more_link_name_ == + other.accessible_learn_more_link_name_; } bool FilesPolicyDialog::Info::operator!=(const Info& other) const { @@ -157,6 +192,10 @@ } } +std::u16string FilesPolicyDialog::Info::GetAccessibleLearnMoreLinkName() const { + return accessible_learn_more_link_name_; +} + bool FilesPolicyDialog::Info::HasCustomDetails() const { return DoesBypassRequireJustification() || HasCustomMessage() || is_custom_learn_more_url_;
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.h b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.h index 4ffcf5f..33cb45b2 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.h +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.h
@@ -126,6 +126,10 @@ // Overrides the default learn more URL. void SetLearnMoreURL(const std::optional<GURL>& url); + // Returns an accessible learn more link name, if available. An empty string + // otherwise. + std::u16string GetAccessibleLearnMoreLinkName() const; + // Returns whether at least one of the default values (e.g., message, learn // more URL, etc...) has been overridden with a custom value. bool HasCustomDetails() const; @@ -149,6 +153,10 @@ // Whether `learn_more_url_` is a custom url. bool is_custom_learn_more_url_ = false; + // Learn more link name providing more info for users using a ChromeVox + // reader. + std::u16string accessible_learn_more_link_name_; + // Default, admin defined learn more URL, or none of them. std::optional<GURL> learn_more_url_; };
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.cc b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.cc index 0718bda..cc01bc704 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.cc +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.cc
@@ -109,6 +109,7 @@ } void AddLearnMoreLink(const std::u16string& text, + const std::u16string& accessible_name, const GURL& url, views::View* view) { views::Link* learn_more_link = @@ -120,6 +121,7 @@ learn_more_link->SetEnabledColor( ash::ColorProvider::Get()->GetContentLayerColor( ash::ColorProvider::ContentLayerType::kTextColorURL)); + learn_more_link->SetAccessibleName(accessible_name); } } // namespace policy::files_dialog_utils
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.h b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.h index be63bd7..39efcce 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.h +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog_utils.h
@@ -27,6 +27,7 @@ // Appends a learn more link to the given `view`. void AddLearnMoreLink(const std::u16string& text, + const std::u16string& accessible_name, const GURL& url, views::View* view);
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.cc b/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.cc index d8e082b2..368a1eb 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.cc +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.cc
@@ -55,18 +55,19 @@ } // Returns learn more links associated with the given `reasons`. -std::set<GURL> GetLearnMoreLinks( +std::vector<std::pair<GURL, std::u16string>> GetLearnMoreLinks( const std::vector<FilesPolicyDialog::BlockReason>& reasons, const std::map<FilesPolicyDialog::BlockReason, FilesPolicyDialog::Info>& dialog_info_map) { - std::set<GURL> links; + std::vector<std::pair<GURL, std::u16string>> links; for (FilesPolicyDialog::BlockReason reason : reasons) { auto it = dialog_info_map.find(reason); if (it == dialog_info_map.end() || !it->second.GetLearnMoreURL().has_value()) { continue; } - links.insert(it->second.GetLearnMoreURL().value()); + links.emplace_back(it->second.GetLearnMoreURL().value(), + it->second.GetAccessibleLearnMoreLinkName()); } return links; } @@ -102,7 +103,7 @@ int view_id, const std::u16string& message, const std::vector<DlpConfidentialFile>& files, - const std::set<GURL>& learn_more_urls) + const std::vector<std::pair<GURL, std::u16string>>& learn_more_urls) : view_id(view_id), message(message), files(files), @@ -127,9 +128,10 @@ // Single error dialog. if (sections_.size() == 1) { const auto& section = sections_.front(); - for (const auto& url : section.learn_more_urls) { + for (const auto& [url, accessible_name] : section.learn_more_urls) { files_dialog_utils::AddLearnMoreLink( - l10n_util::GetStringUTF16(IDS_LEARN_MORE), url, upper_panel_); + l10n_util::GetStringUTF16(IDS_LEARN_MORE), accessible_name, url, + upper_panel_); } for (const auto& file : section.files) { AddConfidentialRow(file.icon, file.title); @@ -260,7 +262,7 @@ ash::TypographyToken::kCrosBody1)); // Add the learn more link if provided. - for (const GURL& url : section.learn_more_urls) { + for (const auto& [url, accessible_name] : section.learn_more_urls) { views::View* learn_more_row = scroll_view_container_->AddChildView(std::make_unique<views::View>()); learn_more_row->SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -268,7 +270,8 @@ gfx::Insets::TLBR(0, 16, 10, 16), 0)); files_dialog_utils::AddLearnMoreLink( - l10n_util::GetStringUTF16(IDS_LEARN_MORE), url, learn_more_row); + l10n_util::GetStringUTF16(IDS_LEARN_MORE), accessible_name, url, + learn_more_row); } for (const auto& file : section.files) {
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.h b/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.h index dcecd5e..a584b5d20 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.h +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_error_dialog.h
@@ -35,10 +35,11 @@ private: // Holds all the information of a section of the dialog. struct BlockedFilesSection { - BlockedFilesSection(int view_id, - const std::u16string& message, - const std::vector<DlpConfidentialFile>& files, - const std::set<GURL>& learn_more_urls); + BlockedFilesSection( + int view_id, + const std::u16string& message, + const std::vector<DlpConfidentialFile>& files, + const std::vector<std::pair<GURL, std::u16string>>& learn_more_urls); ~BlockedFilesSection(); BlockedFilesSection(const BlockedFilesSection& other); @@ -55,10 +56,10 @@ // The blocked files. std::vector<DlpConfidentialFile> files; - // Learn more URLs displayed to the user. Because a section may hold files - // blocked for different reasons, each of which defining its own learn more - // URL, we use a set to collect distinct URLs only. - std::set<GURL> learn_more_urls; + // Learn more URLs displayed to the user and their accessible name read out + // by ChromeVox. A section may hold files blocked for different reasons, + // each of which defining its own learn more URL. + std::vector<std::pair<GURL, std::u16string>> learn_more_urls; }; // PolicyDialogBase overrides:
diff --git a/chrome/browser/ash/policy/dlp/dialogs/files_policy_warn_dialog.cc b/chrome/browser/ash/policy/dlp/dialogs/files_policy_warn_dialog.cc index c53cbba..215f12be 100644 --- a/chrome/browser/ash/policy/dlp/dialogs/files_policy_warn_dialog.cc +++ b/chrome/browser/ash/policy/dlp/dialogs/files_policy_warn_dialog.cc
@@ -140,6 +140,7 @@ if (dialog_info_.GetLearnMoreURL().has_value()) { files_dialog_utils::AddLearnMoreLink( l10n_util::GetStringUTF16(IDS_LEARN_MORE), + dialog_info.GetAccessibleLearnMoreLinkName(), dialog_info_.GetLearnMoreURL().value(), upper_panel_); } MaybeAddConfidentialRows(); @@ -337,6 +338,10 @@ justification_field_->SetID( PolicyDialogBase::kEnterpriseConnectorsJustificationTextareaId); justification_field_->SetAccessibleName(justification_label_text); + justification_field_->SetAccessibleDescription(l10n_util::GetStringFUTF16( + IDS_POLICY_DLP_FILES_JUSTIFICATION_TEXTAREA_ACCESSIBLE_DESCRIPTION, + base::NumberToString16(0), + base::NumberToString16(kMaxBypassJustificationLength))); justification_field_->SetController(this); justification_field_->SetBackgroundColor(SK_ColorTRANSPARENT); justification_field_->SetPreferredSize( @@ -367,6 +372,10 @@ IDS_DEEP_SCANNING_DIALOG_BYPASS_JUSTIFICATION_TEXT_LIMIT_LABEL, base::NumberToString16(new_contents.size()), base::NumberToString16(kMaxBypassJustificationLength))); + justification_field_->SetAccessibleDescription(l10n_util::GetStringFUTF16( + IDS_POLICY_DLP_FILES_JUSTIFICATION_TEXTAREA_ACCESSIBLE_DESCRIPTION, + base::NumberToString16(new_contents.size()), + base::NumberToString16(kMaxBypassJustificationLength))); } if (new_contents.size() == 0 ||
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc index f3eeb60a..094f137 100644 --- a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc +++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc
@@ -159,6 +159,19 @@ return kSystemURLsMap.contains(url.spec()); } +// Return converted `level`. It is converted to kBlock if it is `kWarn` and the +// destination is a system app to avoid spamming the user with warning requests +// for browsing a folder with warned (image) files. +DlpRulesManager::Level ConvertSystemAppWarning( + DlpRulesManager::Level level, + const DlpFileDestination& destination) { + if (level == DlpRulesManager::Level::kWarn && destination.url() && + IsSystemAppURL(*destination.url())) { + return DlpRulesManager::Level::kBlock; + } + return level; +} + } // namespace // static @@ -535,6 +548,8 @@ } } + level = ConvertSystemAppWarning(level, destination); + switch (level) { case DlpRulesManager::Level::kBlock: { files_levels.emplace_back(file, ::dlp::RestrictionLevel::LEVEL_BLOCK);
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_unittest.cc index 0e73d08c..a9d30bf 100644 --- a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_unittest.cc +++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_unittest.cc
@@ -1372,6 +1372,42 @@ base::BucketsAre(base::Bucket(dlp::FileAction::kTransfer, 0))); } +// Warnings to Files app and image loader should be converted to blocks to avoid +// mass warnings when browsing a folder with warned images. +TEST_F(DlpFilesControllerAshTest, BlockWarningFilesOnSystemApps) { + const auto file = DlpFilesControllerAsh::FileDaemonInfo( + kInode1, kCrtime1, base::FilePath(kFilePath1), kExampleUrl1, + kReferrerUrl1); + + base::MockOnceCallback<void( + const std::vector<std::pair<FileDaemonInfo, ::dlp::RestrictionLevel>>&)> + result_callback; + + EXPECT_CALL( + result_callback, + Run(testing::ElementsAre(testing::Pair( + testing::FieldsAre(kInode1, kCrtime1, base::FilePath(kFilePath1), + kExampleUrl1, kReferrerUrl1), + ::dlp::RestrictionLevel::LEVEL_BLOCK)))) + .Times(2); + + EXPECT_CALL(*rules_manager_, IsRestrictedDestination) + .Times(2) + .WillRepeatedly( + testing::DoAll(testing::SetArgPointee<3>(kExampleSourcePattern1), + testing::SetArgPointee<4>(kFileManagerUrl), + testing::SetArgPointee<5>(kRuleMetadata1), + testing::Return(DlpRulesManager::Level::kWarn))); + + files_controller_->IsFilesTransferRestricted( + /*task_id=*/1234, {file}, DlpFileDestination(GURL(kFileManagerUrl)), + dlp::FileAction::kTransfer, result_callback.Get()); + + files_controller_->IsFilesTransferRestricted( + /*task_id=*/1234, {file}, DlpFileDestination(GURL(kImageLoaderUrl)), + dlp::FileAction::kTransfer, result_callback.Get()); +} + TEST_F(DlpFilesControllerAshTest, IsFilesTransferRestricted_MyFiles) { const auto histogram_tester = base::HistogramTester();
diff --git a/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.cc b/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.cc index 28e10b9..6c9d31a 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.cc +++ b/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.cc
@@ -289,11 +289,12 @@ }; remoting::mojom::SupportSessionParamsPtr GetSessionParameters( - const SessionParameters& parameters) { + const SessionParameters& parameters, + std::string_view oauth_token) { auto result = remoting::mojom::SupportSessionParams::New(); result->user_name = parameters.user_name; result->authorized_helper = parameters.admin_email; - result->oauth_access_token = parameters.oauth_token; + result->oauth_access_token = oauth_token; return result; } @@ -400,8 +401,11 @@ class CrdAdminSessionController::NewSessionLauncher : public SessionLauncher { public: NewSessionLauncher(RemotingServiceProxy& remoting_service, + std::unique_ptr<CrdOAuthTokenFetcher> oauth_token_fetcher, const SessionParameters& parameters) - : remoting_service_(remoting_service), parameters_(parameters) {} + : remoting_service_(remoting_service), + oauth_token_fetcher_(std::move(oauth_token_fetcher)), + parameters_(parameters) {} void Launch(SessionLaunchedCallback on_session_launched) override { on_session_launched_ = std::move(on_session_launched); @@ -410,9 +414,23 @@ private: void Start() { + CRD_VLOG(3) << "Fetching OAuth token for CRD session"; + oauth_token_fetcher_->Start(base::BindOnce( + &NewSessionLauncher::ConnectToSession, weak_factory_.GetWeakPtr())); + } + + void ConnectToSession(std::optional<std::string> oauth_token) { + if (!oauth_token.has_value()) { + CRD_LOG(WARNING) << "Failed to fetch OAuth token for CRD session"; + ReportLaunchFailure( + ExtendedStartCrdSessionResultCode::kFailureNoOauthToken); + return; + } + CRD_VLOG(3) << "Starting CRD session with parameters " << parameters_; remoting_service_->StartSession( - GetSessionParameters(parameters_), GetEnterpriseParameters(parameters_), + GetSessionParameters(parameters_, oauth_token.value()), + GetEnterpriseParameters(parameters_), base::BindOnce(&NewSessionLauncher::OnSessionStartResponse, weak_factory_.GetWeakPtr())); } @@ -439,6 +457,7 @@ SessionLaunchedCallback on_session_launched_; raw_ref<RemotingServiceProxy> remoting_service_; + std::unique_ptr<CrdOAuthTokenFetcher> oauth_token_fetcher_; const SessionParameters parameters_; base::WeakPtrFactory<NewSessionLauncher> weak_factory_{this}; @@ -594,7 +613,7 @@ oauth_token_for_test_ = token; } -void CrdAdminSessionController::ClearOAuthTokenForTesting() { +void CrdAdminSessionController::FailOAuthTokenFetchForTesting() { CHECK_IS_TEST(); oauth_token_for_test_.reset(); } @@ -649,8 +668,10 @@ active_session_->AddOwnedObserver(std::make_unique<SessionDurationObserver>( std::move(session_finished_callback))); - active_session_->Launch( - std::make_unique<NewSessionLauncher>(*remoting_service_, parameters)); + active_session_->Launch(std::make_unique<NewSessionLauncher>( + *remoting_service_, + CreateOAuthTokenFetcher(GetOAuthService(), oauth_token_for_test_), + parameters)); } std::unique_ptr<CrdAdminSessionController::CrdHostSession>
diff --git a/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.h b/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.h index 4f88ed4..6b5055e9 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.h +++ b/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.h
@@ -86,7 +86,7 @@ StartCrdSessionJobDelegate& GetDelegate(); void SetOAuthTokenForTesting(std::string_view token); - void ClearOAuthTokenForTesting(); + void FailOAuthTokenFetchForTesting(); private: class CrdHostSession;
diff --git a/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller_unittest.cc b/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller_unittest.cc index 83476ea..f404c736 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller_unittest.cc +++ b/chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller_unittest.cc
@@ -408,6 +408,11 @@ mojo::Remote<SupportHostObserver>& observer_remote() { return observer_; } private: + void SetUp() override { + AshTestBase::SetUp(); + session_controller().SetOAuthTokenForTesting("test-oauth-token"); + } + void TearDown() override { session_controller_.Shutdown(); AshTestBase::TearDown(); @@ -431,14 +436,13 @@ public testing::WithParamInterface<bool> {}; TEST_F(CrdAdminSessionControllerTest, ShouldPassOAuthTokenToRemotingService) { - SessionParameters parameters; - parameters.oauth_token = "<the-oauth-token>"; + session_controller().SetOAuthTokenForTesting("<the-oauth-token>"); SupportSessionParamsPtr actual_parameters; EXPECT_CALL(remoting_service(), StartSession) .WillOnce(SaveParamAndInvokeCallback(&actual_parameters)); - delegate().StartCrdHostAndGetCode(parameters, success_callback(), + delegate().StartCrdHostAndGetCode(SessionParameters{}, success_callback(), error_callback(), session_finished_callback()); @@ -605,6 +609,32 @@ EXPECT_EQ("the-access-code", response.access_code()); } +TEST_F(CrdAdminSessionControllerTest, + ShouldStartSessionIfAccessCodeFetchSucceeds) { + session_controller().SetOAuthTokenForTesting("test-oauth-token"); + + StartCrdHostAndBindObserver(); + + EXPECT_TRUE(delegate().HasActiveSession()); +} + +TEST_F(CrdAdminSessionControllerTest, ShouldReportErrorIfAccessCodeFetchFails) { + session_controller().FailOAuthTokenFetchForTesting(); + + EXPECT_NO_CALLS(remoting_service(), StartSession); + + delegate().StartCrdHostAndGetCode(SessionParameters{}, success_callback(), + error_callback(), + session_finished_callback()); + + Response response = WaitForResponse(); + ASSERT_TRUE(response.HasError()); + EXPECT_EQ(ExtendedStartCrdSessionResultCode::kFailureNoOauthToken, + response.result_code()); + + EXPECT_FALSE(delegate().HasActiveSession()); +} + TEST_F(CrdAdminSessionControllerTest, ShouldReportErrorWhenClientDisconnects) { SupportHostObserver& observer = StartCrdHostAndBindObserver(); @@ -984,7 +1014,6 @@ SessionId id = kValidSessionId) { EXPECT_CALL(remoting_service(), GetReconnectableSessionId) .WillOnce(ReplyWithSessionId(id)); - controller.SetOAuthTokenForTesting("test-oauth-token"); EXPECT_CALL(remoting_service(), ReconnectToSession) .WillOnce([&](remoting::SessionId, const std::string&, StartSupportSessionCallback callback) { @@ -1035,7 +1064,7 @@ ShouldHandleOauthTokenFailureWhileReconnecting) { EnableFeature(kEnableCrdAdminRemoteAccessV2); - session_controller().ClearOAuthTokenForTesting(); + session_controller().FailOAuthTokenFetchForTesting(); // First we should query for the reconnectable session id. EXPECT_CALL(remoting_service(), GetReconnectableSessionId) @@ -1148,7 +1177,7 @@ EXPECT_CALL(remoting_service(), GetReconnectableSessionId) .WillOnce(ReplyWithSessionId(kValidSessionId)); - session_controller().ClearOAuthTokenForTesting(); + session_controller().FailOAuthTokenFetchForTesting(); Init(session_controller()); // The session is destroyed asynchronously.
diff --git a/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.cc b/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.cc index 8143121..bcc4560 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.cc +++ b/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.cc
@@ -130,9 +130,9 @@ void SupportHostObserverProxy::ReportHostStopped( ExtendedStartCrdSessionResultCode result, - const std::string& error_message) { + std::string_view error_message) { for (auto& observer : observers_) { - observer.OnHostStopped(result, error_message); + observer.OnHostStopped(result, std::string{error_message}); } }
diff --git a/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.h b/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.h index 5f2430b..7e5103b 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.h +++ b/chrome/browser/ash/policy/remote_commands/crd/crd_support_host_observer_proxy.h
@@ -9,6 +9,7 @@ #include <memory> #include <optional> #include <string> +#include <string_view> #include <vector> #include "base/observer_list.h" @@ -56,7 +57,7 @@ void OnInvalidDomainError() override; void ReportHostStopped(ExtendedStartCrdSessionResultCode result, - const std::string& error_message); + std::string_view error_message); private: void OnMojomConnectionDropped();
diff --git a/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.cc b/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.cc index d9ab944..cce78b8 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.cc +++ b/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.cc
@@ -25,7 +25,6 @@ #include "base/time/time.h" #include "base/values.h" #include "chrome/browser/ash/policy/remote_commands/crd/crd_logging.h" -#include "chrome/browser/ash/policy/remote_commands/crd/crd_oauth_token_fetcher.h" #include "chrome/browser/ash/policy/remote_commands/crd/crd_remote_command_utils.h" #include "chrome/browser/ash/policy/remote_commands/crd/crd_uma_logger.h" #include "chrome/browser/device_identity/device_oauth2_token_service.h" @@ -131,17 +130,6 @@ return DeviceOAuth2TokenServiceFactory::Get(); } -std::unique_ptr<CrdOAuthTokenFetcher> CreateOAuthTokenFetcher( - DeviceOAuth2TokenService* service, - std::optional<std::string> oauth_token_for_test) { - if (service) { - return std::make_unique<RealCrdOAuthTokenFetcher>(CHECK_DEREF(service)); - } else { - CHECK_IS_TEST(); - return std::make_unique<FakeCrdOAuthTokenFetcher>(oauth_token_for_test); - } -} - std::string GetRobotAccountUserName(const DeviceOAuth2TokenService* service) { CoreAccountId account_id = CHECK_DEREF(service).GetRobotAccountId(); @@ -184,11 +172,8 @@ DeviceCommandStartCrdSessionJob::DeviceCommandStartCrdSessionJob( Delegate& delegate, - std::string_view robot_account_id, - std::optional<std::string> oauth_token) - : oauth_token_for_test_(oauth_token), - delegate_(delegate), - robot_account_id_(robot_account_id) { + std::string_view robot_account_id) + : delegate_(delegate), robot_account_id_(robot_account_id) { CHECK_IS_TEST(); } @@ -262,14 +247,9 @@ // First perform managed network check, CheckManagedNetworkASync( - // Then fetch the OAuth token - base::BindOnce( - &DeviceCommandStartCrdSessionJob::FetchOAuthTokenASync, - weak_factory_.GetWeakPtr(), - // And finally start the CRD host. - base::BindOnce( - &DeviceCommandStartCrdSessionJob::StartCrdHostAndGetCode, - weak_factory_.GetWeakPtr()))); + // Then start the CRD host. + base::BindOnce(&DeviceCommandStartCrdSessionJob::StartCrdHostAndGetCode, + weak_factory_.GetWeakPtr())); } void DeviceCommandStartCrdSessionJob::CheckManagedNetworkASync( @@ -295,25 +275,9 @@ std::move(on_success), GetErrorCallback())); } -void DeviceCommandStartCrdSessionJob::FetchOAuthTokenASync( - OAuthTokenCallback done_callback) { - DCHECK_EQ(oauth_token_fetcher_, nullptr); - - oauth_token_fetcher_ = - CreateOAuthTokenFetcher(GetOAuthService(), oauth_token_for_test_); - oauth_token_fetcher_->Start(std::move(done_callback)); -} - -void DeviceCommandStartCrdSessionJob::StartCrdHostAndGetCode( - std::optional<std::string> oauth_token) { - if (!oauth_token.has_value()) { - return FinishWithError( - ExtendedStartCrdSessionResultCode::kFailureNoOauthToken, ""); - } - - CRD_VLOG(1) << "Received OAuth token, now retrieving CRD access code"; +void DeviceCommandStartCrdSessionJob::StartCrdHostAndGetCode() { + CRD_VLOG(1) << "Starting CRD host and retrieving CRD access code"; SessionParameters parameters; - parameters.oauth_token = std::move(oauth_token).value(); parameters.user_name = robot_account_id_; parameters.terminate_upon_input = ShouldTerminateUponInput(); parameters.show_confirmation_dialog = ShouldShowConfirmationDialog();
diff --git a/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.h b/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.h index 461cf4c..44ff935 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.h +++ b/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_ASH_POLICY_REMOTE_COMMANDS_CRD_DEVICE_COMMAND_START_CRD_SESSION_JOB_H_ #define CHROME_BROWSER_ASH_POLICY_REMOTE_COMMANDS_CRD_DEVICE_COMMAND_START_CRD_SESSION_JOB_H_ -#include <memory> #include <optional> #include <string> #include <string_view> @@ -20,8 +19,6 @@ namespace policy { -class CrdOAuthTokenFetcher; - // Remote command that would start Chrome Remote Desktop host and return auth // code. This command is usable only for devices running Kiosk sessions, for // Affiliated Users and for Managed Guest Sessions. @@ -32,11 +29,8 @@ explicit DeviceCommandStartCrdSessionJob(Delegate& delegate); // Constructor used in unit tests. By using this constructor we avoid the need // for a `DeviceOAuth2TokenService` to exist. - // `oauth_token` will be used as the fetched OAuth token (or the fetch will - // fail if no value is provided). DeviceCommandStartCrdSessionJob(Delegate& delegate, - std::string_view robot_account_id, - std::optional<std::string> oauth_token); + std::string_view robot_account_id); ~DeviceCommandStartCrdSessionJob() override; DeviceCommandStartCrdSessionJob(const DeviceCommandStartCrdSessionJob&) = @@ -51,12 +45,8 @@ void TerminateImpl() override; private: - using OAuthTokenCallback = - base::OnceCallback<void(std::optional<std::string>)>; - void CheckManagedNetworkASync(base::OnceClosure on_success); - void FetchOAuthTokenASync(OAuthTokenCallback done_callback); - void StartCrdHostAndGetCode(std::optional<std::string> oauth_token); + void StartCrdHostAndGetCode(); void FinishWithSuccess(const std::string& access_code); // Finishes command with error code and optional message. void FinishWithError(ExtendedStartCrdSessionResultCode result_code, @@ -76,8 +66,6 @@ Delegate::ErrorCallback GetErrorCallback(); - std::unique_ptr<CrdOAuthTokenFetcher> oauth_token_fetcher_; - // The callback that will be called when the access code was successfully // obtained or when this command failed. CallbackWithResult result_callback_; @@ -99,10 +87,6 @@ // -- End of command parameters -- - // Fake OAuth token that will be used once the next time we need to fetch an - // oauth token. - std::optional<std::string> oauth_token_for_test_; - // The Delegate is used to interact with chrome services and CRD host. const raw_ref<Delegate> delegate_;
diff --git a/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job_unittest.cc b/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job_unittest.cc index 5e74da9..5cf98924 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job_unittest.cc +++ b/chrome/browser/ash/policy/remote_commands/crd/device_command_start_crd_session_job_unittest.cc
@@ -21,8 +21,8 @@ #include "chrome/browser/ash/app_mode/kiosk_chrome_app_manager.h" #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h" #include "chrome/browser/ash/policy/remote_commands/crd/crd_remote_command_utils.h" -#include "chrome/browser/ash/policy/remote_commands/fake_cros_network_config.h" #include "chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.h" +#include "chrome/browser/ash/policy/remote_commands/fake_cros_network_config.h" #include "chrome/browser/ash/policy/remote_commands/user_session_type_test_util.h" #include "chrome/browser/ash/settings/device_settings_test_helper.h" #include "chrome/browser/prefs/browser_prefs.h" @@ -60,7 +60,6 @@ constexpr RemoteCommandJob::UniqueIDType kUniqueID = 123456789; -constexpr char kTestOAuthToken[] = "test-oauth-token"; // Common template used in all UMA histograms for session result logs. constexpr char kHistogramResultTemplate[] = "Enterprise.DeviceRemoteCommand.Crd.%s.%s.Result"; @@ -268,19 +267,14 @@ user_activity_detector_->set_last_activity_time_for_test(value); } - void SetOAuthToken(std::string_view value) { oauth_token_ = value; } - void SetRobotAccountUserName(std::string_view user_name) { robot_account_id_ = user_name; } - void ClearOAuthToken() { oauth_token_ = std::nullopt; } - FakeStartCrdSessionJobDelegate& delegate() { return delegate_; } DeviceCommandStartCrdSessionJob CreateJob() { - return DeviceCommandStartCrdSessionJob{delegate_, robot_account_id_, - oauth_token_}; + return DeviceCommandStartCrdSessionJob{delegate_, robot_account_id_}; } Result RunJobAndWaitForResult(const Payload& payload = Payload()) { @@ -343,7 +337,6 @@ // Parameters passed to the constructor of `DeviceCommandStartCrdSessionJob` // when the job is created. - std::optional<std::string> oauth_token_ = kTestOAuthToken; std::string robot_account_id_ = "robot@account.com"; // Automatically installed as a singleton upon creation. @@ -397,15 +390,6 @@ } TEST_F(DeviceCommandStartCrdSessionJobTest, - ShouldSucceedIfAccessTokenCanBeFetched) { - LogInAsKioskUser(); - - SetOAuthToken(kTestOAuthToken); - - EXPECT_SUCCESS(RunJobAndWaitForResult()); -} - -TEST_F(DeviceCommandStartCrdSessionJobTest, ShouldTerminateActiveSessionAndThenSucceed) { LogInAsKioskUser(); @@ -509,32 +493,16 @@ StartCrdSessionResultCode::FAILURE_UNSUPPORTED_USER_TYPE); } -TEST_F(DeviceCommandStartCrdSessionJobTest, - ShouldFailIfWeCantFetchTheOAuthToken) { - LogInAsKioskUser(); - ClearOAuthToken(); - - EXPECT_ERROR(RunJobAndWaitForResult(), - StartCrdSessionResultCode::FAILURE_NO_OAUTH_TOKEN, ""); -} - TEST_F(DeviceCommandStartCrdSessionJobTest, ShouldFailIfCrdHostReportsAnError) { LogInAsKioskUser(); - delegate().MakeAccessCodeFetchFail(); + delegate().FailWithError( + ExtendedStartCrdSessionResultCode::kFailureCrdHostError); EXPECT_ERROR(RunJobAndWaitForResult(), StartCrdSessionResultCode::FAILURE_CRD_HOST_ERROR); } -TEST_F(DeviceCommandStartCrdSessionJobTest, ShouldPassOAuthTokenToDelegate) { - LogInAsKioskUser(); - SetOAuthToken("the-oauth-token"); - - EXPECT_SUCCESS(RunJobAndWaitForResult()); - EXPECT_EQ("the-oauth-token", delegate().session_parameters().oauth_token); -} - TEST_F(DeviceCommandStartCrdSessionJobTest, ShouldPassRobotAccountNameToDelegate) { LogInAsKioskUser(); @@ -816,7 +784,8 @@ base::HistogramTester histogram_tester; LogInAsKioskUser(); - ClearOAuthToken(); + delegate().FailWithError( + ExtendedStartCrdSessionResultCode::kFailureNoOauthToken); RunJobAndWaitForResult(); histogram_tester.ExpectUniqueSample( @@ -834,7 +803,9 @@ base::HistogramTester histogram_tester; LogInAsKioskUser(); - delegate().MakeAccessCodeFetchFail(); + delegate().FailWithError( + ExtendedStartCrdSessionResultCode::kFailureCrdHostError); + RunJobAndWaitForResult(); histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.cc b/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.cc index 9125454..76c38d80 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.cc +++ b/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.cc
@@ -45,12 +45,11 @@ received_session_parameters_ = parameters; session_finished_callback_ = std::move(session_finished_callback); - if (access_code_success_) { - std::move(success_callback).Run(kTestAccessCode); + if (error_) { + std::move(error_callback).Run(error_.value(), ""); + error_.reset(); } else { - std::move(error_callback) - .Run(ExtendedStartCrdSessionResultCode::kFailureCrdHostError, - std::string()); + std::move(success_callback).Run(kTestAccessCode); } }
diff --git a/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.h b/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.h index 2845104..9f60195 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.h +++ b/chrome/browser/ash/policy/remote_commands/crd/fake_start_crd_session_job_delegate.h
@@ -20,7 +20,9 @@ ~FakeStartCrdSessionJobDelegate() override; void SetHasActiveSession(bool value) { has_active_session_ = value; } - void MakeAccessCodeFetchFail() { access_code_success_ = false; } + void FailWithError(ExtendedStartCrdSessionResultCode error) { + error_ = error; + } void TerminateCrdSession(const base::TimeDelta& session_duration); // Returns if TerminateSession() was called to terminate the active session. @@ -41,8 +43,8 @@ private: bool has_active_session_ = false; - bool access_code_success_ = true; bool terminate_session_called_ = false; + std::optional<ExtendedStartCrdSessionResultCode> error_; std::optional<SessionParameters> received_session_parameters_; std::optional<SessionEndCallback> session_finished_callback_; };
diff --git a/chrome/browser/ash/policy/remote_commands/crd/start_crd_session_job_delegate.h b/chrome/browser/ash/policy/remote_commands/crd/start_crd_session_job_delegate.h index 637e3ab..bea2092 100644 --- a/chrome/browser/ash/policy/remote_commands/crd/start_crd_session_job_delegate.h +++ b/chrome/browser/ash/policy/remote_commands/crd/start_crd_session_job_delegate.h
@@ -34,7 +34,6 @@ SessionParameters(SessionParameters&&); SessionParameters& operator=(SessionParameters&&); - std::string oauth_token = ""; std::string user_name = ""; std::optional<std::string> admin_email; bool terminate_upon_input = false;
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index 3074b63..3efbcb2b 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -658,7 +658,7 @@ AutofillProfile::CreateInferredLabels( std::vector<const AutofillProfile*>(profiles.begin(), profiles.end()), address_only ? absl::make_optional(suggested_fields) : absl::nullopt, - excluded_field, minimal_fields_shown, + {excluded_field}, minimal_fields_shown, g_browser_process->GetApplicationLocale(), &labels); return base::android::ToJavaArrayOfStrings(env, labels);
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index d524249..16e58312d 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -676,8 +676,12 @@ variations::VariationsIdsProvider::GetInstance()); metrics->GetSyntheticTrialRegistry()->AddObserver( variations::SyntheticTrialsActiveGroupIdProvider::GetInstance()); + // TODO(crbug.com/1505638): Investiagte the reason why the mojo connection + // is often created and closed for the same render process on lacros-chrome. +#if !BUILDFLAG(IS_CHROMEOS_LACROS) synthetic_trial_syncer_ = content::SyntheticTrialSyncer::Create( metrics->GetSyntheticTrialRegistry()); +#endif // !BUILDFLAG(IS_CHROMEOS_LACROS) // Now that field trials have been created, initializes metrics recording. metrics->InitializeMetricsRecordingState();
diff --git a/chrome/browser/download/save_package_file_picker.cc b/chrome/browser/download/save_package_file_picker.cc index 6e58edf..56fc2de 100644 --- a/chrome/browser/download/save_package_file_picker.cc +++ b/chrome/browser/download/save_package_file_picker.cc
@@ -222,7 +222,11 @@ ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(), suggested_path_copy, &file_type_info, file_type_index, default_extension_copy, - platform_util::GetTopLevel(web_contents->GetNativeView()), nullptr); + platform_util::GetTopLevel(web_contents->GetNativeView()), + /*params=*/nullptr, /*caller=*/ + web_contents + ? &web_contents->GetPrimaryMainFrame()->GetLastCommittedURL() + : nullptr); return; }
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc index 17e3b3e..65ac6f0 100644 --- a/chrome/browser/download/save_page_browsertest.cc +++ b/chrome/browser/download/save_page_browsertest.cc
@@ -1732,6 +1732,7 @@ auto request = std::get<0>(add_file_cb.Take()); EXPECT_EQ(1, request.add_file_requests().size()); EXPECT_EQ(full_file_name.value(), request.add_file_requests(0).file_path()); + EXPECT_EQ(request.add_file_requests(0).source_url(), url.spec()); base::ScopedAllowBlockingForTesting allow_blocking; EXPECT_TRUE(base::PathExists(full_file_name)); @@ -1760,6 +1761,7 @@ auto request = std::get<0>(add_file_cb.Take()); EXPECT_EQ(1, request.add_file_requests().size()); EXPECT_EQ(full_file_name.value(), request.add_file_requests(0).file_path()); + EXPECT_EQ(request.add_file_requests(0).source_url(), url.spec()); base::ScopedAllowBlockingForTesting allow_blocking; EXPECT_TRUE(base::PathExists(full_file_name));
diff --git a/chrome/browser/extensions/api/printing/printing_test_utils.cc b/chrome/browser/extensions/api/printing/printing_test_utils.cc index cf5da7c..977764482 100644 --- a/chrome/browser/extensions/api/printing/printing_test_utils.cc +++ b/chrome/browser/extensions/api/printing/printing_test_utils.cc
@@ -218,6 +218,7 @@ ConstructPrinterCapabilities() { auto capabilities = std::make_unique<printing::PrinterSemanticCapsAndDefaults>(); + capabilities->bw_model = printing::mojom::ColorModel::kGray; capabilities->color_model = printing::mojom::ColorModel::kColor; capabilities->duplex_default = printing::mojom::DuplexMode::kSimplex; capabilities->duplex_modes.push_back(printing::mojom::DuplexMode::kSimplex);
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc index 7bd394b3..86928ba 100644 --- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc +++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -538,9 +538,6 @@ features.Append(GenerateFeatureFlag( "japanesefunctionrow", base::FeatureList::IsEnabled(ash::features::kJapaneseFunctionRow))); - features.Append(GenerateFeatureFlag( - "virtualkeyboardremovenacl", - base::FeatureList::IsEnabled(ash::features::kVirtualKeyboardRemoveNacl))); results.Set("features", std::move(features));
diff --git a/chrome/browser/lacros/browser_test_util.cc b/chrome/browser/lacros/browser_test_util.cc index 77ac9f30..d38b898d 100644 --- a/chrome/browser/lacros/browser_test_util.cc +++ b/chrome/browser/lacros/browser_test_util.cc
@@ -61,9 +61,11 @@ } bool WaitForWindow(const std::string& id, bool exists) { - CHECK(IsTestControllerAvailable( - crosapi::mojom::TestController::MethodMinVersions:: - kDoesWindowExistMinVersion)); + if (!IsTestControllerAvailable( + crosapi::mojom::TestController::MethodMinVersions:: + kDoesWindowExistMinVersion)) { + return false; + } base::RunLoop outer_loop; bool actual_exists = false; auto wait_for_window = base::BindRepeating( @@ -95,9 +97,11 @@ } bool WaitForElement(const std::string& id, bool exists) { - CHECK(IsTestControllerAvailable( - crosapi::mojom::TestController::MethodMinVersions:: - kDoesElementExistMinVersion)); + if (!IsTestControllerAvailable( + crosapi::mojom::TestController::MethodMinVersions:: + kDoesElementExistMinVersion)) { + return false; + } base::RunLoop outer_loop; bool actual_exists = false; auto wait_for_element = base::BindRepeating( @@ -143,9 +147,11 @@ } bool WaitForShelfItem(const std::string& id, bool exists) { - CHECK(IsTestControllerAvailable( - crosapi::mojom::TestController::MethodMinVersions:: - kDoesItemExistInShelfMinVersion)); + if (!IsTestControllerAvailable( + crosapi::mojom::TestController::MethodMinVersions:: + kDoesItemExistInShelfMinVersion)) { + return false; + } base::RunLoop outer_loop; bool actual_exists = false; auto wait_for_shelf_item = base::BindRepeating( @@ -220,9 +226,11 @@ // |window|. The AuraObserver only waits for the up-event to start processing // before quitting the run loop. bool SendAndWaitForMouseClick(aura::Window* window) { - CHECK( - IsTestControllerAvailable(crosapi::mojom::TestController:: - MethodMinVersions::kClickWindowMinVersion)); + if (!IsTestControllerAvailable( + crosapi::mojom::TestController::MethodMinVersions:: + kClickWindowMinVersion)) { + return false; + } DCHECK(window->IsRootWindow()); std::string id = lacros_window_utility::GetRootWindowUniqueId(window);
diff --git a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.cc index c534478..410f0b4 100644 --- a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.cc
@@ -24,6 +24,12 @@ #define HISTOGRAM_PREFIX "PageLoad.Clients.GoogleSearch." +const char kHistogramGWSNavigationStartToFinalRequestStart[] = + HISTOGRAM_PREFIX "NavigationTiming.NavigationStartToFinalRequestStart"; +const char kHistogramGWSNavigationStartToFinalResponseStart[] = + HISTOGRAM_PREFIX "NavigationTiming.NavigationStartToFinalResponseStart"; +const char kHistogramGWSNavigationStartToFinalLoaderCallback[] = + HISTOGRAM_PREFIX "NavigationTiming.NavigationStartToFinalLoaderCallback"; const char kHistogramGWSNavigationStartToFirstRequestStart[] = HISTOGRAM_PREFIX "NavigationTiming.NavigationStartToFirstRequestStart"; const char kHistogramGWSNavigationStartToFirstResponseStart[] = @@ -148,4 +154,12 @@ PAGE_LOAD_HISTOGRAM( internal::kHistogramGWSNavigationStartToFirstLoaderCallback, timing.first_loader_callback_time - navigation_start_time); + PAGE_LOAD_HISTOGRAM(internal::kHistogramGWSNavigationStartToFinalRequestStart, + timing.final_request_start_time - navigation_start_time); + PAGE_LOAD_HISTOGRAM( + internal::kHistogramGWSNavigationStartToFinalResponseStart, + timing.final_response_start_time - navigation_start_time); + PAGE_LOAD_HISTOGRAM( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, + timing.final_loader_callback_time - navigation_start_time); }
diff --git a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.h index c4d867f..feef11b 100644 --- a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer.h
@@ -12,6 +12,9 @@ namespace internal { // Exposed for tests. +extern const char kHistogramGWSNavigationStartToFinalRequestStart[]; +extern const char kHistogramGWSNavigationStartToFinalResponseStart[]; +extern const char kHistogramGWSNavigationStartToFinalLoaderCallback[]; extern const char kHistogramGWSNavigationStartToFirstRequestStart[]; extern const char kHistogramGWSNavigationStartToFirstResponseStart[]; extern const char kHistogramGWSNavigationStartToFirstLoaderCallback[];
diff --git a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc index 9abc8e1..9fcde9e7d 100644 --- a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc
@@ -85,6 +85,18 @@ tester()->histogram_tester().ExpectBucketCount( internal::kHistogramGWSNavigationStartToFirstLoaderCallback, 1, 1); tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalRequestStart, 1); + tester()->histogram_tester().ExpectBucketCount( + internal::kHistogramGWSNavigationStartToFinalRequestStart, 1, 1); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalResponseStart, 1); + tester()->histogram_tester().ExpectBucketCount( + internal::kHistogramGWSNavigationStartToFinalResponseStart, 1, 1); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, 1); + tester()->histogram_tester().ExpectBucketCount( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, 1, 1); + tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSParseStart, 1); tester()->histogram_tester().ExpectBucketCount( internal::kHistogramGWSParseStart, 1, 1); @@ -121,6 +133,12 @@ tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSNavigationStartToFirstLoaderCallback, 0); tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalRequestStart, 0); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalResponseStart, 0); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, 0); + tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSParseStart, 0); tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSFirstContentfulPaint, 0); @@ -152,6 +170,12 @@ tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSNavigationStartToFirstLoaderCallback, 0); tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalRequestStart, 0); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalResponseStart, 0); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, 0); + tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSParseStart, 0); tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSFirstContentfulPaint, 0); @@ -192,6 +216,18 @@ tester()->histogram_tester().ExpectBucketCount( internal::kHistogramGWSNavigationStartToFirstLoaderCallback, 0, 1); tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalRequestStart, 1); + tester()->histogram_tester().ExpectBucketCount( + internal::kHistogramGWSNavigationStartToFinalRequestStart, 0, 1); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalResponseStart, 1); + tester()->histogram_tester().ExpectBucketCount( + internal::kHistogramGWSNavigationStartToFinalResponseStart, 0, 1); + tester()->histogram_tester().ExpectTotalCount( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, 1); + tester()->histogram_tester().ExpectBucketCount( + internal::kHistogramGWSNavigationStartToFinalLoaderCallback, 0, 1); + tester()->histogram_tester().ExpectTotalCount( internal::kHistogramGWSParseStart, 1); tester()->histogram_tester().ExpectBucketCount( internal::kHistogramGWSParseStart, 0, 1);
diff --git a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc index 44fce061..c072793 100644 --- a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h" +#include "base/trace_event/base_tracing.h" #include "chrome/browser/predictors/loading_predictor.h" #include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/predictors/predictors_features.h" @@ -205,6 +206,35 @@ } void LcpCriticalPathPredictorPageLoadMetricsObserver:: + AppendFetchedSubresourceUrl(const GURL& subresource_url, + const base::TimeDelta& subresource_load_start) { + if (!lcpp_data_inputs_) { + lcpp_data_inputs_.emplace(); + } + if (lcpp_data_inputs_->subresource_urls.empty()) { + base::UmaHistogramMediumTimes( + "Blink.LCPP.NavigationToStartPreload.MainFrame.FirstSubresource.Time", + subresource_load_start); + const base::TimeTicks navigation_start = GetDelegate().GetNavigationStart(); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1( + "loading", "NavigationToStartFirstPreload", TRACE_ID_LOCAL(this), + navigation_start, "url", subresource_url); + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( + "loading", "NavigationToStartFirstPreload", TRACE_ID_LOCAL(this), + navigation_start + subresource_load_start); + } + base::UmaHistogramMediumTimes( + "Blink.LCPP.NavigationToStartPreload.MainFrame.EachSubresource.Time", + subresource_load_start); + if (!lcpp_data_inputs_->subresource_urls.contains(subresource_url)) { + lcpp_data_inputs_->subresource_urls.emplace(subresource_url, + subresource_load_start); + } + // TODO(https://crbug.com/1501673): Save subresource_urls into the LCPP + // database. +} + +void LcpCriticalPathPredictorPageLoadMetricsObserver:: SetLcpInfluencerScriptUrls( const std::vector<GURL>& lcp_influencer_scripts) { if (!lcpp_data_inputs_) {
diff --git a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h index 337389a..7e1495f 100644 --- a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h
@@ -85,6 +85,9 @@ const std::vector<GURL>& lcp_influencer_scripts); // Append fetched font URLs to the list to be passed to LCPP. void AppendFetchedFontUrl(const GURL& font_url); + void AppendFetchedSubresourceUrl( + const GURL& subresource_url, + const base::TimeDelta& subresource_load_start); private: // PageLoadMetricsObserver implementation:
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc index 74b1905f..4304d2b 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc
@@ -99,4 +99,48 @@ plmo->AppendFetchedFontUrl(font_url); } +void LCPCriticalPathPredictorHost::NotifyFetchedSubresource( + const GURL& subresource_url, + base::TimeDelta subresource_load_start) { + if (!base::FeatureList::IsEnabled( + blink::features::kHttpDiskCachePrewarming)) { + ReportBadMessageAndDeleteThis( + "NotifyFetchedSubresource can be called " + "only if kHttpDiskCachePrewarming is enabled."); + return; + } + if (!subresource_url.SchemeIsHTTPOrHTTPS()) { + ReportBadMessageAndDeleteThis("url scheme must be HTTP or HTTPS."); + return; + } + if (subresource_load_start.is_negative()) { + ReportBadMessageAndDeleteThis( + "subresource load start must not be negative value."); + return; + } + static size_t max_url_length = base::checked_cast<size_t>( + blink::features::kHttpDiskCachePrewarmingMaxUrlLength.Get()); + if (subresource_url.spec().length() > max_url_length) { + // The size can be different between KURL and GURL, not reporting + // bad message. + return; + } + // Due to an unresolved bug (crbug.com/1335845), GetForPage can return + // nullptr. + auto* page_data = + LcpCriticalPathPredictorPageLoadMetricsObserver::PageData::GetForPage( + render_frame_host().GetPage()); + if (!page_data) { + return; + } + // `LcpCriticalPathPredictorPageLoadMetricsObserver::OnCommit()` stores + // `LcpCriticalPathPredictorPageLoadMetricsObserver` in `PageData` as a weak + // pointer. This weak pointer can be deleted at any time. + auto* plmo = page_data->GetLcpCriticalPathPredictorPageLoadMetricsObserver(); + if (!plmo) { + return; + } + plmo->AppendFetchedSubresourceUrl(subresource_url, subresource_load_start); +} + } // namespace predictors
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h index 34af374..1614834 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h
@@ -45,6 +45,9 @@ void SetLcpInfluencerScriptUrls( const std::vector<GURL>& lcp_influencer_scripts) override; void NotifyFetchedFont(const GURL& font_url) override; + void NotifyFetchedSubresource( + const GURL& subresource_url, + base::TimeDelta subresource_load_start) override; }; } // namespace predictors
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h index 3307bff..3af1326 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h
@@ -50,6 +50,10 @@ // This field keeps the number of font URLs without omitting due to // reaching `kLCPPFontURLPredictorMaxUrlCountPerOrigin` or deduplication. size_t font_url_count = 0; + // This field keeps the subresource URLs as a key, and the TimeDelta as a + // value. TimeDelta stores the duration from navigation start to resource + // loading start time. + std::map<GURL, base::TimeDelta> subresource_urls; }; bool UpdateLcppDataWithLcppDataInputs(const LoadingPredictorConfig& config,
diff --git a/chrome/browser/printing/web_api/web_printing_browsertest.cc b/chrome/browser/printing/web_api/web_printing_browsertest.cc index 219ae75e7..5dec9b6 100644 --- a/chrome/browser/printing/web_api/web_printing_browsertest.cc +++ b/chrome/browser/printing/web_api/web_printing_browsertest.cc
@@ -236,6 +236,8 @@ "separate-documents-uncollated-copies", "separate-documents-collated-copies" ], + "printColorModeDefault": "monochrome", + "printColorModeSupported": [ "monochrome", "color" ], "printerName": "name", "sidesDefault": "one-sided", "sidesSupported": [ "one-sided" ]
diff --git a/chrome/browser/printing/web_api/web_printing_mojom_traits.cc b/chrome/browser/printing/web_api/web_printing_mojom_traits.cc index 14c5a32..4155a9c 100644 --- a/chrome/browser/printing/web_api/web_printing_mojom_traits.cc +++ b/chrome/browser/printing/web_api/web_printing_mojom_traits.cc
@@ -6,6 +6,7 @@ #include "base/strings/utf_string_conversions.h" #include "mojo/public/cpp/bindings/type_converter.h" +#include "printing/mojom/print.mojom-shared.h" #include "third_party/blink/public/mojom/printing/web_printing.mojom.h" namespace mojo { @@ -18,6 +19,26 @@ // multiple-document-handling: using MultipleDocumentHandling = blink::mojom::WebPrintingMultipleDocumentHandling; + +// print-color-mode: +using PrintColorMode = blink::mojom::WebPrintColorMode; +using printing::mojom::ColorModel; + +// This is not typemapped via EnumTraits<> due to issues with handling `auto` +// PrintColorMode (which doesn't represent a color model and hence has to be +// processed separately). +// As for specializing a TypeConverter<> -- since this function is not exposed +// publicly, we'd like to avoid potential ODR violations if someone decides to +// implement a converter between these two types elsewhere. +ColorModel PrintColorModeToColorModel(PrintColorMode print_color_mode) { + switch (print_color_mode) { + case PrintColorMode::kColor: + return ColorModel::kColorModeColor; + case PrintColorMode::kMonochrome: + return ColorModel::kColorModeMonochrome; + } +} + } // namespace // static @@ -86,6 +107,9 @@ break; } } + if (auto print_color_mode = data.print_color_mode()) { + settings->set_color(PrintColorModeToColorModel(*print_color_mode)); + } *out = std::move(settings); return true;
diff --git a/chrome/browser/printing/web_api/web_printing_mojom_traits.h b/chrome/browser/printing/web_api/web_printing_mojom_traits.h index 46bab93..03589a2 100644 --- a/chrome/browser/printing/web_api/web_printing_mojom_traits.h +++ b/chrome/browser/printing/web_api/web_printing_mojom_traits.h
@@ -48,6 +48,10 @@ const std::unique_ptr<printing::PrintSettings>& ptr) { NOTREACHED_NORETURN(); } + static const std::optional<blink::mojom::WebPrintColorMode>& print_color_mode( + const std::unique_ptr<printing::PrintSettings>& ptr) { + NOTREACHED_NORETURN(); + } static const std::optional<blink::mojom::WebPrintingSides>& sides( const std::unique_ptr<printing::PrintSettings>& ptr) { NOTREACHED_NORETURN();
diff --git a/chrome/browser/printing/web_api/web_printing_service_chromeos.cc b/chrome/browser/printing/web_api/web_printing_service_chromeos.cc index df17d0996..093f66f 100644 --- a/chrome/browser/printing/web_api/web_printing_service_chromeos.cc +++ b/chrome/browser/printing/web_api/web_printing_service_chromeos.cc
@@ -16,6 +16,7 @@ #include "content/public/browser/render_frame_host.h" #include "printing/backend/print_backend.h" #include "printing/metafile_skia.h" +#include "printing/print_settings.h" #include "printing/printed_document.h" namespace printing { @@ -35,6 +36,14 @@ return response ? response->capabilities : std::nullopt; } +bool IsDuplexModeKnown(mojom::DuplexMode duplex_mode) { + return duplex_mode != mojom::DuplexMode::kUnknownDuplexMode; +} + +bool IsColorModelKnown(mojom::ColorModel color_model) { + return color_model != mojom::ColorModel::kUnknownColorModel; +} + bool ValidatePrintJobTemplateAttributesAgainstPrinterAttributes( const PrintSettings& pjt_attributes, const PrinterSemanticCapsAndDefaults& printer_attributes) { @@ -45,14 +54,37 @@ if (pjt_attributes.collate() && !printer_attributes.collate_capable) { return false; } - if (pjt_attributes.duplex_mode() != mojom::DuplexMode::kUnknownDuplexMode && + // Checks that printer supports color printing if requested so. + if (IsColorModelKnown(pjt_attributes.color()) && + ::printing::IsColorModelSelected(pjt_attributes.color()).value() && + !IsColorModelKnown(printer_attributes.color_model)) { + return false; + } + if (IsDuplexModeKnown(pjt_attributes.duplex_mode()) && !base::Contains(printer_attributes.duplex_modes, pjt_attributes.duplex_mode())) { return false; } + if (!IsDuplexModeKnown(pjt_attributes.duplex_mode()) && + !IsDuplexModeKnown(printer_attributes.duplex_default)) { + return false; + } return true; } +void UpdatePrintJobTemplateAttributesWithPrinterDefaults( + PrintSettings* pjt_attributes, + const PrinterSemanticCapsAndDefaults& printer_attributes) { + if (!IsDuplexModeKnown(pjt_attributes->duplex_mode())) { + pjt_attributes->set_duplex_mode(printer_attributes.duplex_default); + } + if (!IsColorModelKnown(pjt_attributes->color())) { + pjt_attributes->set_color(printer_attributes.color_default + ? mojom::ColorModel::kColorModeColor + : mojom::ColorModel::kColorModeMonochrome); + } +} + } // namespace WebPrintingServiceChromeOS::WebPrintingServiceChromeOS( @@ -129,6 +161,9 @@ blink::mojom::WebPrintError::kPrintJobTemplateAttributesMismatch)); return; } + // Update selected fields to printer defaults if they're not specified. + UpdatePrintJobTemplateAttributesWithPrinterDefaults(pjt_attributes.get(), + *printer_attributes); pdf_flattener_->ReadAndFlattenPdf( std::move(document),
diff --git a/chrome/browser/printing/web_api/web_printing_type_converters.cc b/chrome/browser/printing/web_api/web_printing_type_converters.cc index d6d4b41a..ded030c2 100644 --- a/chrome/browser/printing/web_api/web_printing_type_converters.cc +++ b/chrome/browser/printing/web_api/web_printing_type_converters.cc
@@ -57,6 +57,19 @@ } } +void ProcessPrintColorMode(const PrinterSemanticCapsAndDefaults& caps, + blink::mojom::WebPrinterAttributes* attributes) { + attributes->print_color_mode_default = + caps.color_default ? blink::mojom::WebPrintColorMode::kColor + : blink::mojom::WebPrintColorMode::kMonochrome; + attributes->print_color_mode_supported.push_back( + blink::mojom::WebPrintColorMode::kMonochrome); + if (caps.color_model != mojom::ColorModel::kUnknownColorModel) { + attributes->print_color_mode_supported.push_back( + blink::mojom::WebPrintColorMode::kColor); + } +} + void ProcessSides(const PrinterSemanticCapsAndDefaults& caps, blink::mojom::WebPrinterAttributes* attributes) { if (caps.duplex_default != mojom::DuplexMode::kUnknownDuplexMode) { @@ -74,7 +87,6 @@ attributes->sides_supported)) { attributes->sides_default.reset(); attributes->sides_supported.clear(); - return; } } @@ -91,6 +103,7 @@ printing::ProcessCopies(capabilities, attributes.get()); printing::ProcessMultipleDocumentHandling(capabilities, attributes.get()); + printing::ProcessPrintColorMode(capabilities, attributes.get()); printing::ProcessSides(capabilities, attributes.get()); return attributes;
diff --git a/chrome/browser/resources/chromeos/app_install/app_install_dialog.ts b/chrome/browser/resources/chromeos/app_install/app_install_dialog.ts index a6d6748..d8a7f14 100644 --- a/chrome/browser/resources/chromeos/app_install/app_install_dialog.ts +++ b/chrome/browser/resources/chromeos/app_install/app_install_dialog.ts
@@ -78,7 +78,7 @@ const installButton = this.$<CrButtonElement>('.install-button')!; assert(installButton); installButton.addEventListener( - 'click', this.onInstallButtonClick.bind(this)); + 'click', this.onInstallButtonClick.bind(this), {once: true}); } private onCancelButtonClick(): void { @@ -100,17 +100,25 @@ new Promise(resolve => setTimeout(resolve, 2000)), ]); + installButton.disabled = false; if (install_result) { // TODO(crbug.com/1488697): Localize string. installButton.textContent = 'Open app'; installButton.classList.replace('installing', 'installed'); + installButton.addEventListener( + 'click', this.onOpenAppButtonClick.bind(this)); } else { - // TODO(crbug.com/1488697): Proper error display. + // TODO(crbug.com/1488697): Proper error display and/or allow install to + // be attempted again. installButton.textContent = loadTimeData.getString('install'); installButton.classList.replace('installing', 'install'); - installButton.disabled = false; } } + + private async onOpenAppButtonClick() { + this.proxy.handler.launchApp(); + this.proxy.handler.closeDialog(); + } } customElements.define(AppInstallDialogElement.is, AppInstallDialogElement);
diff --git a/chrome/browser/screen_ai/screen_ai_install_state.cc b/chrome/browser/screen_ai/screen_ai_install_state.cc index 25d1e316..45eaabea 100644 --- a/chrome/browser/screen_ai/screen_ai_install_state.cc +++ b/chrome/browser/screen_ai/screen_ai_install_state.cc
@@ -191,11 +191,18 @@ } void ScreenAIInstallState::SetState(State state) { + // TODO(crbug.com/1508404): Remove after crash root cause is found. + if ((state == State::kDownloaded || state == State::kReady) && + !IsComponentAvailable()) { + base::debug::DumpWithoutCrashing(); + state = State::kFailed; + } + if (state == state_) { // Failed and ready state can be repeated as they come from different // profiles. Downloading can be repeated in ChromeOS tests that call // LoginManagerTest::AddUser() and reset UserSessionInitializer. - // TODO(crbug.com/1278249): While the case is highly unexpected, add more + // TODO(crbug.com/1443341): While the case is highly unexpected, add more // control logic if state is changed from failed to ready or vice versa. DCHECK(state == State::kReady || state == State::kFailed || state == State::kDownloading); @@ -243,6 +250,9 @@ void ScreenAIInstallState::SetStateForTesting(State state) { state_ = state; + for (ScreenAIInstallState::Observer* observer : observers_) { + observer->StateChanged(state_); + } } } // namespace screen_ai
diff --git a/chrome/browser/screen_ai/screen_ai_service_router.cc b/chrome/browser/screen_ai/screen_ai_service_router.cc index 9057a4f..c2b7679 100644 --- a/chrome/browser/screen_ai/screen_ai_service_router.cc +++ b/chrome/browser/screen_ai/screen_ai_service_router.cc
@@ -7,6 +7,8 @@ #include <utility> #include "base/containers/flat_map.h" +#include "base/debug/alias.h" +#include "base/debug/dump_without_crashing.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -141,22 +143,32 @@ void ScreenAIServiceRouter::LaunchIfNotRunning() { ScreenAIInstallState::GetInstance()->SetLastUsageTime(); + auto* state_instance = ScreenAIInstallState::GetInstance(); + screen_ai::ScreenAIInstallState::State install_state = + state_instance->get_state(); if (screen_ai_service_factory_.is_bound() || - screen_ai::ScreenAIInstallState::GetInstance()->get_state() == - screen_ai::ScreenAIInstallState::State::kFailed) { + install_state == screen_ai::ScreenAIInstallState::State::kFailed) { return; } - auto* screen_ai_install = ScreenAIInstallState::GetInstance(); + // TODO(crbug.com/1508404): Remove after crash root cause is found, or replace + // above. + if (install_state != screen_ai::ScreenAIInstallState::State::kDownloaded && + install_state != screen_ai::ScreenAIInstallState::State::kReady) { + base::debug::Alias(&install_state); + base::debug::DumpWithoutCrashing(); + return; + } + // Callers of the service should ensure that the component is downloaded // before promising it to the users and triggering its launch. - CHECK(screen_ai_install->IsComponentAvailable()) + CHECK(state_instance->IsComponentAvailable()) << "ScreenAI service launch triggered when component is not " "available."; #if BUILDFLAG(IS_WIN) - base::FilePath library_path = screen_ai_install->get_component_binary_path(); + base::FilePath library_path = state_instance->get_component_binary_path(); std::vector<base::FilePath> preload_libraries = {library_path}; #endif // BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 228f161d7..3bb8677 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2494,6 +2494,8 @@ "../ash/app_list/search/util/ftrl_optimizer.h", "../ash/app_list/search/util/keyword_cache.cc", "../ash/app_list/search/util/keyword_cache.h", + "../ash/app_list/search/util/manatee.cc", + "../ash/app_list/search/util/manatee.h", "../ash/app_list/search/util/mrfu_cache.cc", "../ash/app_list/search/util/mrfu_cache.h", "../ash/app_list/search/util/persistent_proto.h",
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerFactory.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerFactory.java index b389b7e..4ce8e80b 100644 --- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerFactory.java +++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerFactory.java
@@ -42,7 +42,9 @@ return new EdgeToEdgeControllerImpl(activity, tabObservableSupplier, null); } - /** @Return whether the feature is enabled or not. */ + /** + * @return whether the feature is enabled or not. + */ public static boolean isEnabled() { // Make sure we test SDK version before checking the Feature so Field Trials only collect // from qualifying devices.
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc index 817baa9..bccc0ec 100644 --- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -294,14 +294,9 @@ // Choose something from the bookmark submenu and make sure it makes it back // to the delegate as well. - size_t bookmarks_model_index = 0; - for (size_t i = 0; i < item_count; ++i) { - if (model.GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU) { - // The bookmarks submenu comes after the Tabs and Downloads items. - bookmarks_model_index = i + (features::IsChromeRefresh2023() ? 3 : 2); - break; - } - } + size_t bookmarks_model_index = + model.GetIndexOfCommandId(IDC_BOOKMARKS_MENU).value(); + EXPECT_GT(bookmarks_model_index, 0u); ui::MenuModel* bookmarks_model = model.GetSubmenuModelAt(bookmarks_model_index);
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc index 582d0ed8..b6b4efc3 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc
@@ -53,6 +53,7 @@ #include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ui_base_features.h" using ::testing::ElementsAre; @@ -615,43 +616,83 @@ RecentTabsSubMenuModel model(nullptr, browser()); - // Expected menu items: - std::vector<ModelData> kData = { - {ui::MenuModel::TYPE_COMMAND, true}, // History - {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> - {ui::MenuModel::TYPE_COMMAND, false}, // Recently closed - {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> - {ui::MenuModel::TYPE_TITLE, false}, // <section header for session 3> - {ui::MenuModel::TYPE_COMMAND, true}, // <tab for session 3> - {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> - {ui::MenuModel::TYPE_TITLE, false}, // <section header for session 2> - {ui::MenuModel::TYPE_COMMAND, true}, // <tab for session 2> - {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> - {ui::MenuModel::TYPE_TITLE, false}, // <section header for session 1> - {ui::MenuModel::TYPE_COMMAND, true}, // <tab for session 1> - // max sessions is 3, so only the 3 most recent sessions will show. - }; + std::vector<ModelData> kData; + // Once chrome refresh is launched this if condition can be removed. + if (!features::IsChromeRefresh2023()) { + kData = { + {ui::MenuModel::TYPE_COMMAND, true}, // History + {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> + {ui::MenuModel::TYPE_COMMAND, false}, // Recently closed + {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> + {ui::MenuModel::TYPE_TITLE, false}, // <section header for session 3> + {ui::MenuModel::TYPE_COMMAND, true}, // <tab for session 3> + {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> + {ui::MenuModel::TYPE_TITLE, false}, // <section header for session 2> + {ui::MenuModel::TYPE_COMMAND, true}, // <tab for session 2> + {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> + {ui::MenuModel::TYPE_TITLE, false}, // <section header for session 1> + {ui::MenuModel::TYPE_COMMAND, true}, // <tab for session 1> + // max sessions is 3, so only the 3 most recent sessions will show. + }; - if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { - kData.insert(kData.begin() + 1, - {ui::MenuModel::TYPE_COMMAND, true}); // History Cluster - } + if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { + kData.insert(kData.begin() + 1, + {ui::MenuModel::TYPE_COMMAND, true}); // History Cluster + } - VerifyModel(model, kData); + VerifyModel(model, kData); - if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { - EXPECT_THAT(base::span<const std::u16string>( - recent_tabs_builder.GetTabTitlesSortedByRecency()) - .subspan(0, 3), - ElementsAre(model.GetLabelAt(6), model.GetLabelAt(9), - model.GetLabelAt(12))); + if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { + EXPECT_THAT(base::span<const std::u16string>( + recent_tabs_builder.GetTabTitlesSortedByRecency()) + .subspan(0, 3), + ElementsAre(model.GetLabelAt(6), model.GetLabelAt(9), + model.GetLabelAt(12))); + + } else { + EXPECT_THAT(base::span<const std::u16string>( + recent_tabs_builder.GetTabTitlesSortedByRecency()) + .subspan(0, 3), + ElementsAre(model.GetLabelAt(5), model.GetLabelAt(8), + model.GetLabelAt(11))); + } } else { - EXPECT_THAT(base::span<const std::u16string>( - recent_tabs_builder.GetTabTitlesSortedByRecency()) - .subspan(0, 3), - ElementsAre(model.GetLabelAt(5), model.GetLabelAt(8), - model.GetLabelAt(11))); + kData = {{ui::MenuModel::TYPE_COMMAND, true}, // History + {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> + {ui::MenuModel::TYPE_COMMAND, false}, // Recently closed + {ui::MenuModel::TYPE_SEPARATOR, true}, // <separator> + {ui::MenuModel::TYPE_TITLE, false}, // Your devices + {ui::MenuModel::TYPE_SUBMENU, true}, + {ui::MenuModel::TYPE_SUBMENU, true}, + {ui::MenuModel::TYPE_SUBMENU, true}, + {ui::MenuModel::TYPE_SUBMENU, true}}; + + if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { + kData.insert(kData.begin() + 1, + {ui::MenuModel::TYPE_COMMAND, true}); // History Cluster + } + + VerifyModel(model, kData); + + if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { + EXPECT_THAT(base::span<const std::u16string>( + recent_tabs_builder.GetTabTitlesSortedByRecency()) + .subspan(0, 4), + ElementsAre(model.GetSubmenuModelAt(6)->GetLabelAt(0), + model.GetSubmenuModelAt(7)->GetLabelAt(0), + model.GetSubmenuModelAt(8)->GetLabelAt(0), + model.GetSubmenuModelAt(9)->GetLabelAt(0))); + + } else { + EXPECT_THAT(base::span<const std::u16string>( + recent_tabs_builder.GetTabTitlesSortedByRecency()) + .subspan(0, 4), + ElementsAre(model.GetSubmenuModelAt(5)->GetLabelAt(0), + model.GetSubmenuModelAt(6)->GetLabelAt(0), + model.GetSubmenuModelAt(7)->GetLabelAt(0), + model.GetSubmenuModelAt(8)->GetLabelAt(0))); + } } }
diff --git a/chrome/browser/ui/views/permissions/chip_controller.cc b/chrome/browser/ui/views/permissions/chip_controller.cc index b813608..261896e0 100644 --- a/chrome/browser/ui/views/permissions/chip_controller.cc +++ b/chrome/browser/ui/views/permissions/chip_controller.cc
@@ -473,13 +473,6 @@ } } -void ChipController::OnOcclusionStateChanged(bool occluded) { - if (GetBubbleWidget()) { - // Disable the prompt if it's occluded by a picture-in-picture window. - GetBubbleWidget()->GetContentsView()->SetEnabled(!occluded); - } -} - void ChipController::HideChip() { if (!chip_->GetVisible()) return; @@ -561,7 +554,6 @@ parent_was_visible_when_activation_changed_ = prompt_bubble_widget->GetPrimaryWindowWidget()->IsVisible(); prompt_bubble_widget->AddObserver(this); - occlusion_observation_.Observe(prompt_bubble_widget); } }
diff --git a/chrome/browser/ui/views/permissions/chip_controller.h b/chrome/browser/ui/views/permissions/chip_controller.h index 908302366..76c1b020b 100644 --- a/chrome/browser/ui/views/permissions/chip_controller.h +++ b/chrome/browser/ui/views/permissions/chip_controller.h
@@ -11,8 +11,6 @@ #include "base/check_is_test.h" #include "base/functional/callback_helpers.h" #include "base/timer/timer.h" -#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h" -#include "chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h" #include "chrome/browser/ui/views/location_bar/omnibox_chip_button.h" #include "components/permissions/permission_prompt.h" #include "components/permissions/permission_request_manager.h" @@ -40,8 +38,7 @@ class ChipController : public permissions::PermissionRequestManager::Observer, public views::WidgetObserver, public BubbleOwnerDelegate, - public OmniboxChipButton::Observer, - public PictureInPictureOcclusionObserver { + public OmniboxChipButton::Observer { public: ChipController(Browser* browser_, OmniboxChipButton* chip_view); @@ -82,9 +79,6 @@ void OnExpandAnimationEnded() override; void OnCollapseAnimationEnded() override; - // PictureInPictureOcclusionObserver: - void OnOcclusionStateChanged(bool occluded) override; - // Initializes the permission prompt model as well as the permission request // manager and observes the prompt bubble. void InitializePermissionPrompt( @@ -243,8 +237,6 @@ base::ScopedObservation<OmniboxChipButton, OmniboxChipButton::Observer> observation_{this}; - ScopedPictureInPictureOcclusionObservation occlusion_observation_{this}; - base::WeakPtrFactory<ChipController> weak_factory_{this}; };
diff --git a/chrome/browser/ui/views/permissions/permission_chip_interactive_test.cc b/chrome/browser/ui/views/permissions/permission_chip_interactive_test.cc index 8b1c8a66..5246a536 100644 --- a/chrome/browser/ui/views/permissions/permission_chip_interactive_test.cc +++ b/chrome/browser/ui/views/permissions/permission_chip_interactive_test.cc
@@ -8,8 +8,6 @@ #include "base/time/time.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_config.h" #include "chrome/browser/permissions/quiet_notification_permission_ui_state.h" -#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h" -#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" @@ -45,7 +43,6 @@ #include "content/public/test/browser_test.h" #include "content/public/test/permissions_test_utils.h" #include "content/public/test/test_navigation_observer.h" -#include "media/base/media_switches.h" #include "net/dns/mock_host_resolver.h" #include "permission_prompt_chip.h" #include "ui/accessibility/ax_action_data.h" @@ -1648,71 +1645,3 @@ EXPECT_TRUE(content::EvalJs(main_rfh, kCheckNotifications).value.GetBool()); } - -class PictureInPictureOcclusionTrackingEnabledPermissionChipInteractiveTest - : public PermissionChipInteractiveTest { - public: - PictureInPictureOcclusionTrackingEnabledPermissionChipInteractiveTest() { - scoped_feature_list_.InitWithFeatures( - {media::kPictureInPictureOcclusionTracking}, {}); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -IN_PROC_BROWSER_TEST_F( - PictureInPictureOcclusionTrackingEnabledPermissionChipInteractiveTest, - ShouldHideChipWhenOccludedByAPictureInPictureWindow) { - RequestPermission(permissions::RequestType::kGeolocation); - base::RunLoop().RunUntilIdle(); - - // Chip should be visible. Click it to open the prompt. - EXPECT_TRUE(GetChip()->GetVisible()); - ClickOnChip(GetChip()); - - views::View* prompt_view = - GetChipController()->GetBubbleWidget()->GetContentsView(); - ASSERT_NE(prompt_view, nullptr); - - // Create a picture-in-picture widget that does not occlude the prompt. - gfx::Rect prompt_widget_bounds = - prompt_view->GetWidget()->GetWindowBoundsInScreen(); - gfx::Rect non_occluding_bounds = - gfx::Rect(prompt_widget_bounds.right() + 1, 0, 100, 100); - views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW); - init_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - init_params.bounds = non_occluding_bounds; - auto pip_widget = std::make_unique<views::Widget>(std::move(init_params)); - pip_widget->Show(); - PictureInPictureWindowManager::GetInstance() - ->GetOcclusionTracker() - ->OnPictureInPictureWidgetOpened(pip_widget.get()); - - // The prompt should be enabled, as it's not occluded. - EXPECT_TRUE(prompt_view->GetEnabled()); - - // Move the picture-in-picture window to occlude the prompt. - pip_widget->SetBounds(prompt_widget_bounds); - - // The prompt should be disabled. We may need to wait for that to happen. - if (prompt_view->GetEnabled()) { - base::RunLoop wait_loop; - auto subscription = - prompt_view->AddEnabledChangedCallback(wait_loop.QuitClosure()); - wait_loop.Run(); - } - EXPECT_FALSE(prompt_view->GetEnabled()); - - // Move the picture-in-picture window to no longer occlude the prompt. - pip_widget->SetBounds(non_occluding_bounds); - - // The prompt should be enabled again. We may need to wait for that to happen. - if (!prompt_view->GetEnabled()) { - base::RunLoop wait_loop; - auto subscription = - prompt_view->AddEnabledChangedCallback(wait_loop.QuitClosure()); - wait_loop.Run(); - } - EXPECT_TRUE(prompt_view->GetEnabled()); -}
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble.cc b/chrome/browser/ui/views/permissions/permission_prompt_bubble.cc index 886aa57..8addff3 100644 --- a/chrome/browser/ui/views/permissions/permission_prompt_bubble.cc +++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble.cc
@@ -48,7 +48,6 @@ disallowed_custom_cursors_scope_ = delegate()->GetAssociatedWebContents()->CreateDisallowCustomCursorScope(); - occlusion_observation_.Observe(prompt_bubble->GetWidget()); } void PermissionPromptBubble::CleanUpPromptBubble() { @@ -142,10 +141,3 @@ return static_cast<const PermissionPromptBubbleBaseView*>( prompt_bubble_tracker_.view()); } - -void PermissionPromptBubble::OnOcclusionStateChanged(bool occluded) { - // Disable the prompt if it's occluded by a picture-in-picture window. - if (GetPromptBubble()) { - GetPromptBubble()->GetWidget()->GetContentsView()->SetEnabled(!occluded); - } -}
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble.h b/chrome/browser/ui/views/permissions/permission_prompt_bubble.h index 278ebaf..a1bd0b6 100644 --- a/chrome/browser/ui/views/permissions/permission_prompt_bubble.h +++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble.h
@@ -6,8 +6,6 @@ #define CHROME_BROWSER_UI_VIEWS_PERMISSIONS_PERMISSION_PROMPT_BUBBLE_H_ #include "chip_controller.h" -#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h" -#include "chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h" #include "chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.h" #include "chrome/browser/ui/views/permissions/permission_prompt_desktop.h" #include "content/public/browser/web_contents_observer.h" @@ -19,8 +17,7 @@ } class PermissionPromptBubble : public PermissionPromptDesktop, - public views::WidgetObserver, - public PictureInPictureOcclusionObserver { + public views::WidgetObserver { public: PermissionPromptBubble(Browser* browser, content::WebContents* web_contents, @@ -44,9 +41,6 @@ views::Widget* GetPromptBubbleWidgetForTesting() override; - // PictureInPictureOcclusionObserver: - void OnOcclusionStateChanged(bool occluded) override; - private: PermissionPromptBubbleBaseView* GetPromptBubble(); const PermissionPromptBubbleBaseView* GetPromptBubble() const; @@ -61,8 +55,6 @@ base::ScopedClosureRunner disallowed_custom_cursors_scope_; - ScopedPictureInPictureOcclusionObservation occlusion_observation_{this}; - base::WeakPtrFactory<PermissionPromptBubble> weak_factory_{this}; };
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc index ff9447ce..017bcf3 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
@@ -1152,8 +1152,9 @@ GetLastLinkOpenedMetadataFromPostMessage()); } +// TODO(crbug.com/1511189): Flaky test. IN_PROC_BROWSER_TEST_F(CompanionPageBrowserTest, - PageTitleNotifiesViaPostMessage) { + DISABLED_PageTitleNotifiesViaPostMessage) { EnablePco(true); ASSERT_TRUE(ui_test_utils::NavigateToURL( browser(), GURL("data:text/html;charset=utf-8,"
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc index 08a006f..eec882a8 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc
@@ -751,16 +751,9 @@ // The hover card should stop showing memory usage data after navigating to // another site since the data is now out of date -// TODO(crbug.com/1483255): Flaky on mac -#if BUILDFLAG(IS_MAC) -#define MAYBE_HoverCardStopShowingMemoryOnNavigation \ - DISABLED_HoverCardStopShowingMemoryOnNavigation -#else -#define MAYBE_HoverCardStopShowingMemoryOnNavigation \ - HoverCardStopShowingMemoryOnNavigation -#endif +// TODO(crbug.com/1483255): Re-enable after resolving flakiness. IN_PROC_BROWSER_TEST_P(TabHoverCardFadeFooterInteractiveUiTest, - MAYBE_HoverCardStopShowingMemoryOnNavigation) { + DISABLED_HoverCardStopShowingMemoryOnNavigation) { RunTestSequence( InstrumentTab(kFirstTabContents, 0), NavigateWebContents(kFirstTabContents, GetTestingURL("a.com")),
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc index 8e081a39..6e3afb42 100644 --- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -1681,6 +1681,20 @@ ASSERT_EQ(blue, EvalJs(web_contents, get_background_color)); } +// Verifies that draggable and non draggable regions defined by the app-region +// CSS property are collected. +IN_PROC_BROWSER_TEST_F(WebAppFrameToolbarBrowserTest_WindowControlsOverlay, + DraggableRegionsEnabled) { + InstallAndLaunchWebApp(); + ToggleWindowControlsOverlayAndWait(); + + absl::optional<SkRegion> draggable_region = + helper()->browser_view()->browser()->app_controller()->draggable_region(); + + EXPECT_TRUE(draggable_region.has_value()); + EXPECT_FALSE(draggable_region.value().isEmpty()); +} + #if !BUILDFLAG(IS_ANDROID) class WebAppFrameToolbarBrowserTest_AdditionalWindowingControls : public WebAppFrameToolbarBrowserTest {
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 9b110ff..8ed48f7 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -4569,7 +4569,9 @@ enabled_features.push_back(blink::features::kDesktopPWAsTabStrip); enabled_features.push_back(features::kDesktopPWAsTabStripSettings); #if BUILDFLAG(IS_CHROMEOS_ASH) - // TODO(crbug.com/1462253): Also test with Lacros flags enabled. + // WebAppIntegrationTest runs in Ash only when Lacros is disabled. + // If Lacros is enabled, WebAppIntegrationTest runs in Lacros with crosapi + // enabled. base::Extend(disabled_features, ash::standalone_browser::GetFeatureRefs()); #endif #if BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc index f736e53..c12c2ce 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_render_frame.mojom.h" #include "chrome/common/pref_names.h" #include "chrome/common/themes/autogenerated_theme_util.h" #include "chrome/grit/generated_resources.h" @@ -37,9 +38,12 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "extensions/common/constants.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/features.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/models/image_model.h" @@ -129,6 +133,7 @@ has_tab_strip_(has_tab_strip), theme_provider_( ThemeService::CreateBoundThemeProvider(browser_->profile(), this)) { + CHECK(browser->tab_strip_model()->empty()); browser->tab_strip_model()->AddObserver(this); } @@ -609,9 +614,27 @@ void AppBrowserController::OnTabInserted(content::WebContents* contents) { if (!contents->GetVisibleURL().is_empty() && initial_url_.is_empty()) SetInitialURL(contents->GetVisibleURL()); + + // Collect draggable app regions if the app supports Window Controls Overlay + // or Borderless mode. + if (AppUsesWindowControlsOverlay() || AppUsesBorderlessMode()) { + content::RenderFrameHost* host = contents->GetPrimaryMainFrame(); + DCHECK(host); + mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame> client; + host->GetRemoteAssociatedInterfaces()->GetInterface(&client); + client->SetSupportsAppRegion(true); + } } -void AppBrowserController::OnTabRemoved(content::WebContents* contents) {} +void AppBrowserController::OnTabRemoved(content::WebContents* contents) { + // Stop collecting draggable app regions when the web contents is removed + // since it may be reparented to a tab in the browser. + content::RenderFrameHost* host = contents->GetPrimaryMainFrame(); + DCHECK(host); + mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame> client; + host->GetRemoteAssociatedInterfaces()->GetInterface(&client); + client->SetSupportsAppRegion(false); +} ui::ImageModel AppBrowserController::GetFallbackAppIcon() const { TRACE_EVENT0("ui", "TaskManagerView::GetFallbackAppIcon");
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc index a579f56..57edf00 100644 --- a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
@@ -106,7 +106,8 @@ WebAppInstalledCallback installed_callback, const webapps::AppId& app_id, webapps::InstallResultCode code) { - dialog_handle->SetInstallSuccess(webapps::IsSuccess(code)); + dialog_handle->SetInstallComplete(webapps::IsSuccess(code) ? &app_id + : nullptr); // If we receive an error code, there's a chance the dialog was never shown, // so we need to clean it up to avoid a memory leak.
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install.mojom b/chrome/browser/ui/webui/ash/app_install/app_install.mojom index a64d4fe..7196a38 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install.mojom +++ b/chrome/browser/ui/webui/ash/app_install/app_install.mojom
@@ -37,4 +37,7 @@ // Runs the callback to install the app and returns whether the app was // successfully installed. InstallApp() => (bool installed); + + // Opens the app that was just installed, then closes the dialog. + LaunchApp(); };
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_dialog.cc b/chrome/browser/ui/webui/ash/app_install/app_install_dialog.cc index 96248fc..6cf9e59 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_dialog.cc +++ b/chrome/browser/ui/webui/ash/app_install/app_install_dialog.cc
@@ -37,9 +37,9 @@ this->ShowSystemDialog(parent); } -void AppInstallDialog::SetInstallSuccess(bool success) { +void AppInstallDialog::SetInstallComplete(const std::string* app_id) { if (dialog_ui_) { - dialog_ui_->SetInstallSuccess(success); + dialog_ui_->SetInstallComplete(app_id); } }
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_dialog.h b/chrome/browser/ui/webui/ash/app_install/app_install_dialog.h index 107f624..d434e50 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_dialog.h +++ b/chrome/browser/ui/webui/ash/app_install/app_install_dialog.h
@@ -26,8 +26,9 @@ void Show(gfx::NativeWindow parent, mojom::DialogArgsPtr args, base::OnceCallback<void(bool accepted)> dialog_accepted_callback); - // Callers must set whether the install was successful or not. - void SetInstallSuccess(bool success); + // Callers must call this once the install has finished, passing in the app_id + // if the installation succeeded or a nullptr if it failed. + void SetInstallComplete(const std::string* app_id); void OnDialogShown(content::WebUI* webui) override;
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_dialog_browsertest.cc b/chrome/browser/ui/webui/ash/app_install/app_install_dialog_browsertest.cc index 420023f..26b437b 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_dialog_browsertest.cc +++ b/chrome/browser/ui/webui/ash/app_install/app_install_dialog_browsertest.cc
@@ -5,13 +5,17 @@ #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" #include "chrome/browser/ui/webui/ash/app_install/app_install_dialog.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" +#include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_install_params.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/webui_url_constants.h" +#include "chrome/test/base/chrome_test_utils.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/constants/chromeos_features.h" @@ -87,6 +91,24 @@ "querySelector('.action-button').textContent.includes('Open app')") .ExtractBool()) { } + + // Click the open app button and expect the dialog was closed. + content::WebContentsDestroyedWatcher watcher(web_contents); + EXPECT_TRUE( + content::ExecJs(web_contents, + "document.querySelector('app-install-dialog')." + "shadowRoot.querySelector('.action-button').click()")); + watcher.Wait(); + + // Expect the app is opened. + webapps::AppId app_id = web_app::GenerateAppIdFromManifestId(app_url); + Browser* app_browser = BrowserList::GetInstance()->GetLastActive(); + EXPECT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser, app_id)); + + // Expect the browser tab was not closed. + EXPECT_EQ( + browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL(), + app_url); } IN_PROC_BROWSER_TEST_F(AppInstallDialogBrowserTest, FailedInstall) { @@ -97,13 +119,14 @@ base::WeakPtr<AppInstallDialog> dialog_handle = AppInstallDialog::CreateDialog(); - dialog_handle->Show( - browser()->window()->GetNativeWindow(), - ash::app_install::mojom::DialogArgs::New(), - base::BindOnce( - [](base::WeakPtr<AppInstallDialog> dialog_handle, - bool dialog_accepted) { dialog_handle->SetInstallSuccess(false); }, - dialog_handle)); + dialog_handle->Show(browser()->window()->GetNativeWindow(), + ash::app_install::mojom::DialogArgs::New(), + base::BindOnce( + [](base::WeakPtr<AppInstallDialog> dialog_handle, + bool dialog_accepted) { + dialog_handle->SetInstallComplete(nullptr); + }, + dialog_handle)); navigation_observer_dialog.Wait(); ASSERT_TRUE(navigation_observer_dialog.last_navigation_succeeded());
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.cc b/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.cc index b614539..789ec724 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.cc +++ b/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.cc
@@ -4,16 +4,21 @@ #include "chrome/browser/ui/webui/ash/app_install/app_install_page_handler.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/ash/app_install/app_install.mojom.h" +#include "components/services/app_service/public/cpp/app_launch_util.h" namespace ash::app_install { AppInstallPageHandler::AppInstallPageHandler( + Profile* profile, mojom::DialogArgsPtr args, base::OnceCallback<void(bool accepted)> dialog_accepted_callback, mojo::PendingReceiver<mojom::PageHandler> pending_page_handler, CloseDialogCallback close_dialog_callback) - : dialog_args_{std::move(args)}, + : profile_{profile}, + dialog_args_{std::move(args)}, dialog_accepted_callback_{std::move(dialog_accepted_callback)}, receiver_{this, std::move(pending_page_handler)}, close_dialog_callback_{std::move(close_dialog_callback)} {} @@ -41,10 +46,22 @@ std::move(dialog_accepted_callback_).Run(true); } -void AppInstallPageHandler::OnInstallComplete(bool success) { - if (install_app_callback_) { - std::move(install_app_callback_).Run(success); +void AppInstallPageHandler::OnInstallComplete(const std::string* app_id) { + if (app_id) { + app_id_ = *app_id; } + if (install_app_callback_) { + std::move(install_app_callback_).Run(/*success=*/app_id); + } +} + +void AppInstallPageHandler::LaunchApp() { + if (app_id_.empty()) { + mojo::ReportBadMessage("Unable to launch app without an app_id."); + return; + } + apps::AppServiceProxyFactory::GetForProfile(profile_)->Launch( + app_id_, ui::EF_NONE, apps::LaunchSource::kFromInstaller); } } // namespace ash::app_install
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.h b/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.h index db9d5718..b9d0749 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.h +++ b/chrome/browser/ui/webui/ash/app_install/app_install_page_handler.h
@@ -5,8 +5,11 @@ #ifndef CHROME_BROWSER_UI_WEBUI_ASH_APP_INSTALL_APP_INSTALL_PAGE_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_ASH_APP_INSTALL_APP_INSTALL_PAGE_HANDLER_H_ +#include <string> + #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/ash/app_install/app_install.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -21,6 +24,7 @@ public: using CloseDialogCallback = base::OnceCallback<void()>; explicit AppInstallPageHandler( + Profile* profile, mojom::DialogArgsPtr args, base::OnceCallback<void(bool accepted)> dialog_accepted_callback, mojo::PendingReceiver<mojom::PageHandler> pending_page_handler, @@ -31,19 +35,22 @@ ~AppInstallPageHandler() override; - void OnInstallComplete(bool success); + void OnInstallComplete(const std::string* app_id); // mojom::PageHandler: void GetDialogArgs(GetDialogArgsCallback callback) override; void CloseDialog() override; void InstallApp(InstallAppCallback callback) override; + void LaunchApp() override; private: + raw_ptr<Profile> profile_; mojom::DialogArgsPtr dialog_args_; base::OnceCallback<void(bool accepted)> dialog_accepted_callback_; mojo::Receiver<mojom::PageHandler> receiver_; CloseDialogCallback close_dialog_callback_; InstallAppCallback install_app_callback_; + std::string app_id_; base::WeakPtrFactory<AppInstallPageHandler> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_ui.cc b/chrome/browser/ui/webui/ash/app_install/app_install_ui.cc index def400d..bf6888b 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_ui.cc +++ b/chrome/browser/ui/webui/ash/app_install/app_install_ui.cc
@@ -54,11 +54,11 @@ dialog_accepted_callback_ = std::move(dialog_accepted_callback); } -void AppInstallDialogUI::SetInstallSuccess(bool success) { +void AppInstallDialogUI::SetInstallComplete(const std::string* app_id) { if (!page_handler_) { return; } - page_handler_->OnInstallComplete(success); + page_handler_->OnInstallComplete(app_id); } void AppInstallDialogUI::BindInterface( @@ -72,8 +72,8 @@ void AppInstallDialogUI::CreatePageHandler( mojo::PendingReceiver<mojom::PageHandler> receiver) { page_handler_ = std::make_unique<AppInstallPageHandler>( - std::move(dialog_args_), std::move(dialog_accepted_callback_), - std::move(receiver), + Profile::FromWebUI(web_ui()), std::move(dialog_args_), + std::move(dialog_accepted_callback_), std::move(receiver), base::BindOnce(&AppInstallDialogUI::CloseDialog, base::Unretained(this))); }
diff --git a/chrome/browser/ui/webui/ash/app_install/app_install_ui.h b/chrome/browser/ui/webui/ash/app_install/app_install_ui.h index 9dcc89b..f55ebc53 100644 --- a/chrome/browser/ui/webui/ash/app_install/app_install_ui.h +++ b/chrome/browser/ui/webui/ash/app_install/app_install_ui.h
@@ -24,7 +24,7 @@ void SetDialogArgs(mojom::DialogArgsPtr args); void SetDialogCallback( base::OnceCallback<void(bool accepted)> dialog_accepted_callback); - void SetInstallSuccess(bool success); + void SetInstallComplete(const std::string* app_id); // Instantiates the implementor of the mojom::PageHandlerFactory mojo // interface passing the pending receiver that will be internally bound.
diff --git a/chrome/browser/ui/webui/ash/settings/pages/a11y/pdf_ocr_handler_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/a11y/pdf_ocr_handler_unittest.cc index 4b147fc..5319e50 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/a11y/pdf_ocr_handler_unittest.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/a11y/pdf_ocr_handler_unittest.cc
@@ -130,7 +130,7 @@ } void SimulateSetState(screen_ai::ScreenAIInstallState::State state) { - test_screen_ai_install_state_->SetState(state); + test_screen_ai_install_state_->SetStateForTesting(state); } content::TestWebUI* test_web_ui() const { return test_web_ui_.get(); }
diff --git a/chrome/browser/ui/webui/settings/accessibility_main_handler_unittest.cc b/chrome/browser/ui/webui/settings/accessibility_main_handler_unittest.cc index 6dd47c7..791f10d 100644 --- a/chrome/browser/ui/webui/settings/accessibility_main_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/accessibility_main_handler_unittest.cc
@@ -120,7 +120,7 @@ } void SimulateSetState(screen_ai::ScreenAIInstallState::State state) { - test_screen_ai_install_state_->SetState(state); + test_screen_ai_install_state_->SetStateForTesting(state); } content::TestWebUI* test_web_ui() const { return test_web_ui_.get(); }
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index acd312ad..d19a6b1 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -65,7 +65,6 @@ #include "chrome/browser/web_applications/web_app_command_scheduler.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" -#include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" @@ -213,14 +212,6 @@ } } - // On some devices, Adobe Express is installed through App Preload Service - // as an OEM app, but should not appear in the OEM folder. - // TODO(b/300857328): Remove this workaround. - if (web_app->GetHighestPrioritySource() == WebAppManagement::kOem && - web_app->app_id() == web_app::kAdobeExpressAppId) { - return apps::InstallReason::kDefault; - } - switch (web_app->GetHighestPrioritySource()) { case WebAppManagement::kSystem: return apps::InstallReason::kSystem; @@ -1638,8 +1629,11 @@ HostContentSettingsMapFactory::GetForProfile(profile_)); #if BUILDFLAG(IS_CHROMEOS) - notification_display_service_.Observe( - NotificationDisplayServiceFactory::GetForProfile(profile())); + // NotificationDisplayService could be null in some tests. + if (auto* notification_display_service = + NotificationDisplayServiceFactory::GetForProfile(profile())) { + notification_display_service_.Observe(notification_display_service); + } badge_manager_ = badging::BadgeManagerFactory::GetForProfile(profile()); // badge_manager_ is nullptr in guest and incognito profiles.
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc index f4d3e0c..e6ce6256 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper_unittest.cc
@@ -322,59 +322,6 @@ EXPECT_EQ(file_cond.condition_values[1]->value, ".txt"); } -// Verify that Adobe Express has its OEM install source overwritten as -// InstallReason::kDefault. -// TODO(b/300857328): Remove this workaround. -TEST_F(WebAppPublisherHelperTest, PublishOemAdobeExpressAsDefault) { - const std::string name = "some app name"; - const GURL start_url("https://example.com/start_url"); - - // Manually edit the database to create an app with the specific App ID but a - // non-matching start URL. - { - ScopedRegistryUpdate update = provider_->sync_bridge_unsafe().BeginUpdate(); - - auto new_app = std::make_unique<WebApp>(kAdobeExpressAppId); - new_app->SetStartUrl(start_url); - new_app->AddSource(WebAppManagement::Type::kOem); - new_app->SetName(name); - - update->CreateApp(std::move(new_app)); - } - - const WebApp* web_app = - provider_->registrar_unsafe().GetAppById(kAdobeExpressAppId); - - apps::AppPtr app = publisher_->CreateWebApp(web_app); - EXPECT_EQ(app->install_reason, apps::InstallReason::kDefault); -} - -// Verify that the above behavior only applies when the app is OEM-installed. -// TODO(b/300857328): Remove this workaround. -TEST_F(WebAppPublisherHelperTest, PublishSyncAdobeExpressAsSync) { - const std::string name = "some app name"; - const GURL start_url("https://example.com/start_url"); - - // Manually edit the database to create an app with the specific App ID but a - // non-matching start URL. - { - ScopedRegistryUpdate update = provider_->sync_bridge_unsafe().BeginUpdate(); - - auto new_app = std::make_unique<WebApp>(kAdobeExpressAppId); - new_app->SetStartUrl(start_url); - new_app->AddSource(WebAppManagement::Type::kSync); - new_app->SetName(name); - - update->CreateApp(std::move(new_app)); - } - - const WebApp* web_app = - provider_->registrar_unsafe().GetAppById(kAdobeExpressAppId); - - apps::AppPtr app = publisher_->CreateWebApp(web_app); - EXPECT_EQ(app->install_reason, apps::InstallReason::kSync); -} - #if BUILDFLAG(IS_CHROMEOS) TEST_F(WebAppPublisherHelperTest, UpdateShortcutDoesNotPublishDelta) { EnableCrosWebAppShortcutUiUpdate(true);
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/feed/FeedSurfaceScopeDependencyProvider.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/feed/FeedSurfaceScopeDependencyProvider.java index 7dd7ca4..995fd21e 100644 --- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/feed/FeedSurfaceScopeDependencyProvider.java +++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/feed/FeedSurfaceScopeDependencyProvider.java
@@ -125,7 +125,7 @@ * Adds a header offset observer to the surface this scope is associated with. * * @param observer The observer to add. - * @Return a reference to be used when removing the observer, or null if not successful. + * @return a reference to be used when removing the observer, or null if not successful. */ default void addHeaderOffsetObserver(SurfaceHeaderOffsetObserver observer) {}
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 90d0a46..00da537 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1702425214-915c1314fa46f8dbbb5bf3cfd8d8a86c1896adc2.profdata +chrome-android32-main-1702447123-bed2e5fe15bf2185c87941cc65b80896d4126b24.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 35bd600..e8fd13a9 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1702425214-14c0ac1ffc03747544aa7a7cf4c0a61557c0b42f.profdata +chrome-android64-main-1702447123-a38d1365b5e43a01cd21d9e5b20a6497833bfbd1.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 14cfc7d..360c5505 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1702425214-c0eeefb29930be2c4e15f71c555b06034cc26f56.profdata +chrome-linux-main-1702447123-266f7fc8e5fce15ba880d22bef2d48878e563c4d.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 72bbf93..0a858318 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1702432768-94aea22f9e9b926edeb7c28cc770df1bfae9ddff.profdata +chrome-mac-arm-main-1702461414-8ea1afeac8e596a108ef03d039c19dc2c7531899.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index d44343ba..6465eedb 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1702425214-1fdb9a0a29f3689c8e41dfe04aedc8409376b4b1.profdata +chrome-mac-main-1702447123-b3d1bd65b3dc0ca24f49b4e68bb71073949cbf3b.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index bdc14a0..99b5135 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1702425214-5e919e3462b94a38d972768c6c40f439958542b5.profdata +chrome-win-arm64-main-1702447123-78c1140c790c3a9c0e62c2af90cbd845e5349689.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index d6363a1..03428c2 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1702425214-5070cd26284fc4b60e0b182054fcf04b72f2bb33.profdata +chrome-win32-main-1702447123-a31776760bdc4ea37f254d84b09aee737ef69edc.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9916f7f..a04c736f 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1702425214-bc7d81d4f7f7000ffc8054316eef6b5b4f620ce8.profdata +chrome-win64-main-1702447123-9223de7885538ed24977d864c1dd4a142590be3f.profdata
diff --git a/chrome/common/chrome_render_frame.mojom b/chrome/common/chrome_render_frame.mojom index 92c421e..05f928d 100644 --- a/chrome/common/chrome_render_frame.mojom +++ b/chrome/common/chrome_render_frame.mojom
@@ -68,4 +68,8 @@ // Tells the render frame to load any blocked plugins matching the given // identifier (empty string matches all). LoadBlockedPlugins(string identifier); + + // Indicates that the frame should collect draggable regions set using the + // app-region CSS property. + SetSupportsAppRegion(bool supports_app_region); };
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index d514ff1e..ef842d9 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -576,6 +576,10 @@ #endif // BUILDFLAG(ENABLE_PLUGINS) } +void ChromeRenderFrameObserver::SetSupportsAppRegion(bool supports_app_region) { + render_frame()->GetWebView()->SetSupportsAppRegion(supports_app_region); +} + void ChromeRenderFrameObserver::SetClientSidePhishingDetection() { #if BUILDFLAG(SAFE_BROWSING_AVAILABLE) phishing_classifier_ = safe_browsing::PhishingClassifierDelegate::Create(
diff --git a/chrome/renderer/chrome_render_frame_observer.h b/chrome/renderer/chrome_render_frame_observer.h index 073d3a5..2ad51aa9 100644 --- a/chrome/renderer/chrome_render_frame_observer.h +++ b/chrome/renderer/chrome_render_frame_observer.h
@@ -107,6 +107,7 @@ #endif void GetMediaFeedURL(GetMediaFeedURLCallback callback) override; void LoadBlockedPlugins(const std::string& identifier) override; + void SetSupportsAppRegion(bool supports_app_region) override; // Initialize a |phishing_classifier_delegate_|. void SetClientSidePhishingDetection();
diff --git a/chrome/test/base/chromeos/ash_browser_test_starter.cc b/chrome/test/base/chromeos/ash_browser_test_starter.cc index f4b3065..cf495d40d 100644 --- a/chrome/test/base/chromeos/ash_browser_test_starter.cc +++ b/chrome/test/base/chromeos/ash_browser_test_starter.cc
@@ -201,8 +201,7 @@ void AshBrowserTestStarter::StartLacros(InProcessBrowserTest* test_class_obj) { DCHECK(HasLacrosArgument()); - crosapi::BrowserManager::Get()->set_device_ownership_waiter_for_testing( - std::make_unique<crosapi::FakeDeviceOwnershipWaiter>()); + SetUpBrowserManager(); { NewLacrosWindowWatcher watcher; @@ -215,6 +214,13 @@ CHECK(crosapi::BrowserManager::Get()->IsRunning()); } +void AshBrowserTestStarter::SetUpBrowserManager() { + DCHECK(HasLacrosArgument()); + + crosapi::BrowserManager::Get()->set_device_ownership_waiter_for_testing( + std::make_unique<crosapi::FakeDeviceOwnershipWaiter>()); +} + void AshBrowserTestStarter::OnWindowDestroying(aura::Window* window) { DCHECK_EQ(window, initial_lacros_window_); initial_lacros_window_ = nullptr;
diff --git a/chrome/test/base/chromeos/ash_browser_test_starter.h b/chrome/test/base/chromeos/ash_browser_test_starter.h index 8626a0a..217c774 100644 --- a/chrome/test/base/chromeos/ash_browser_test_starter.h +++ b/chrome/test/base/chromeos/ash_browser_test_starter.h
@@ -40,6 +40,9 @@ // this no earlier than SetUpOnMainThread(). void StartLacros(InProcessBrowserTest* test_class_obj); + // Sets the browser manager's ownership waiter to a test fake. + void SetUpBrowserManager(); + net::EmbeddedTestServer* https_server(); GURL base_url();
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js index 2e9f32f..bc82dfd 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_browsertest.js
@@ -51,7 +51,8 @@ ['SearchBoxTest', 'search_box_test.js'], ['SearchResultRowTest', 'search_result_row_test.js'], ['SearchResultBoldingTest', 'search_result_bolding_test.js'], - ['ShortcutCustomizationApp', 'shortcut_customization_test.js'], + // TODO(https://crbug.com/1498419): Tests are flaky. + // ['ShortcutCustomizationApp', 'shortcut_customization_test.js'], ['ShortcutSearchHandlerTest', 'shortcut_search_handler_test.js'], ['ShortcutsPageTest', 'shortcuts_page_test.js'], ['ShortcutUtils', 'shortcut_utils_test.js'],
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts index 99910e02..85ae18f 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts +++ b/chrome/test/data/webui/chromeos/shortcut_customization/shortcut_customization_test.ts
@@ -1416,32 +1416,25 @@ strictQuery('search-box', getPage().shadowRoot, SearchBoxElement); let searchField = strictQuery( '#search', searchBox.shadowRoot, CrToolbarSearchFieldElement); - - // Verify that the search field is focused by default when the app opens. - await flushTasks(); - assertTrue(searchField.isSearchFocused()); - - // Remove focus from the search field. - searchField.blur(); - searchBox = - strictQuery('search-box', getPage().shadowRoot, SearchBoxElement); - searchField = strictQuery( - '#search', searchBox.shadowRoot, CrToolbarSearchFieldElement); - - // Confirm that the search field is no longer focused. - await flushTasks(); assertFalse(searchField.isSearchFocused()); - // Trigger the 'handleFindShortcut' function. - getPage().handleFindShortcut(/*modalContextOpen=*/ false); + // press ctrl + f. + const keyboardEvent = new KeyboardEvent('keydown', { + key: 'f', + keyCode: 70, + code: 'KeyF', + ctrlKey: true, + altKey: false, + shiftKey: false, + metaKey: false, + }); + getPage().dispatchEvent(keyboardEvent); + await flushTasks(); searchBox = strictQuery('search-box', getPage().shadowRoot, SearchBoxElement); searchField = strictQuery( '#search', searchBox.shadowRoot, CrToolbarSearchFieldElement); - - // Verify that the search field is focused. - await flushTasks(); assertTrue(searchField.isSearchFocused()); }); });
diff --git a/chrome/test/data/webui/cr_components/most_visited_test.ts b/chrome/test/data/webui/cr_components/most_visited_test.ts index 6976164f..274b59b 100644 --- a/chrome/test/data/webui/cr_components/most_visited_test.ts +++ b/chrome/test/data/webui/cr_components/most_visited_test.ts
@@ -1067,6 +1067,10 @@ })); await flushTasks(); const reorderCalled = handler.whenCalled('reorderMostVisitedTile'); + document.dispatchEvent(new DragEvent('drop', { + clientX: secondRect.x + 1, + clientY: secondRect.y + 1, + })); document.dispatchEvent(new DragEvent('dragend', { clientX: secondRect.x + 1, clientY: secondRect.y + 1, @@ -1096,6 +1100,10 @@ })); await flushTasks(); const reorderCalled = handler.whenCalled('reorderMostVisitedTile'); + document.dispatchEvent(new DragEvent('drop', { + clientX: firstRect.x + 1, + clientY: firstRect.y + 1, + })); document.dispatchEvent(new DragEvent('dragend', { clientX: firstRect.x + 1, clientY: firstRect.y + 1, @@ -1123,6 +1131,10 @@ clientX: firstRect.x + firstRect.width / 2, clientY: firstRect.y + firstRect.height / 2, })); + document.dispatchEvent(new DragEvent('drop', { + clientX: secondRect.x + 1, + clientY: secondRect.y + 1, + })); document.dispatchEvent(new DragEvent('dragend', { clientX: secondRect.x + 1, clientY: secondRect.y + 1,
diff --git a/chromeos/ash/components/language_packs/language_pack_manager.cc b/chromeos/ash/components/language_packs/language_pack_manager.cc index c7b833cb..3dc3971 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager.cc +++ b/chromeos/ash/components/language_packs/language_pack_manager.cc
@@ -7,9 +7,11 @@ #include <optional> #include <string_view> +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "base/containers/contains.h" #include "base/containers/flat_map.h" +#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/functional/callback_helpers.h" @@ -455,11 +457,22 @@ } void LanguagePackManager::CheckAndUpdateDlcsForInputMethods( - PrefService* prefs) { + PrefService* pref_service) { // The list of input methods have changed. We need to get the list of current // DLCs installed on device, which is an asynchronous method. DlcserviceClient::Get()->GetExistingDlcs( - base::BindOnce(&OnGetExistingDlcs, prefs)); + base::BindOnce(&OnGetExistingDlcs, pref_service)); +} + +void LanguagePackManager::ObservePrefs(PrefService* pref_service) { + // This is the main gate for the functionality of observing Prefs. + // If this flag is false, all of the cascading logic is disabled. + if (base::FeatureList::IsEnabled(features::kLanguagePacksInSettings)) { + pref_change_registrar_.Init(pref_service); + base::RepeatingClosure callback = base::BindRepeating( + &LanguagePackManager::CheckAndUpdateDlcsForInputMethods, pref_service); + pref_change_registrar_.Add(ash::prefs::kLanguagePreloadEngines, callback); + } } void LanguagePackManager::AddObserver(Observer* const observer) { @@ -503,6 +516,7 @@ LanguagePackManager::~LanguagePackManager() { CHECK_EQ(g_instance, this); + pref_change_registrar_.RemoveAll(); g_instance = nullptr; }
diff --git a/chromeos/ash/components/language_packs/language_pack_manager.h b/chromeos/ash/components/language_packs/language_pack_manager.h index 6b9ffa2..ba780b1 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager.h +++ b/chromeos/ash/components/language_packs/language_pack_manager.h
@@ -15,6 +15,8 @@ #include "base/scoped_observation.h" #include "base/strings/strcat.h" #include "chromeos/ash/components/dbus/dlcservice/dlcservice_client.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_service.h" #include "ui/base/ime/ash/input_method_util.h" class PrefService; @@ -236,6 +238,9 @@ static void UpdatePacksForOobe(const std::string& locale, OnUpdatePacksForOobeCallback callback); + // Registers itself as an Observer of all the relevant languages Prefs. + void ObservePrefs(PrefService* pref_service); + // Adds an observer to the observer list. void AddObserver(Observer* observer); @@ -272,7 +277,7 @@ // Retrieves the list of installed DLCs and updates Packs accordingly. // This function should be called when LPM initializes and then each time // Prefs change. - static void CheckAndUpdateDlcsForInputMethods(PrefService* prefs); + static void CheckAndUpdateDlcsForInputMethods(PrefService* pref_service); // DlcserviceClient::Observer overrides. void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override; @@ -285,6 +290,7 @@ base::ObserverList<Observer> observers_; base::ScopedObservation<DlcserviceClient, DlcserviceClient::Observer> obs_{ this}; + PrefChangeRegistrar pref_change_registrar_; }; } // namespace ash::language_packs
diff --git a/components/autofill/core/browser/autofill_field_unittest.cc b/components/autofill/core/browser/autofill_field_unittest.cc index cd2ee7ec..f024f259 100644 --- a/components/autofill/core/browser/autofill_field_unittest.cc +++ b/components/autofill/core/browser/autofill_field_unittest.cc
@@ -6,6 +6,7 @@ #include "base/test/scoped_feature_list.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_features.h" #include "testing/gtest/include/gtest/gtest.h" @@ -447,5 +448,56 @@ .heuristic_type = ADDRESS_HOME_APT_NUM, .expected_result = ADDRESS_HOME_CITY})); +// Tests that consecutive identical events are not added twice to the event log. +TEST(AutofillFieldLogEventTypeTest, AppendLogEventIfNotRepeated) { + // The following three FieldLogEventTypes are arbitrary besides being of + // distinct types. + AutofillField::FieldLogEventType a = AskForValuesToFillFieldLogEvent{ + .has_suggestion = OptionalBoolean::kFalse, + .suggestion_is_shown = OptionalBoolean::kFalse}; + AutofillField::FieldLogEventType a2 = AskForValuesToFillFieldLogEvent{ + .has_suggestion = OptionalBoolean::kTrue, + .suggestion_is_shown = OptionalBoolean::kTrue}; + AutofillField::FieldLogEventType b = + TriggerFillFieldLogEvent{.data_type = FillDataType::kUndefined, + .associated_country_code = "DE", + .timestamp = AutofillClock::Now()}; + AutofillField::FieldLogEventType c = FillFieldLogEvent{ + .fill_event_id = absl::get<TriggerFillFieldLogEvent>(b).fill_event_id, + .had_value_before_filling = OptionalBoolean::kTrue, + .autofill_skipped_status = + FieldFillingSkipReason::kAutofilledFieldsNotRefill, + .was_autofilled = OptionalBoolean::kTrue, + .had_value_after_filling = OptionalBoolean::kTrue}; + + AutofillField f; + EXPECT_TRUE(f.field_log_events().empty()); + + f.AppendLogEventIfNotRepeated(a); + EXPECT_EQ(f.field_log_events().size(), 1u); + f.AppendLogEventIfNotRepeated(a); + EXPECT_EQ(f.field_log_events().size(), 1u); + + f.AppendLogEventIfNotRepeated(a2); + EXPECT_EQ(f.field_log_events().size(), 2u); + f.AppendLogEventIfNotRepeated(a2); + EXPECT_EQ(f.field_log_events().size(), 2u); + + f.AppendLogEventIfNotRepeated(b); + EXPECT_EQ(f.field_log_events().size(), 3u); + f.AppendLogEventIfNotRepeated(b); + EXPECT_EQ(f.field_log_events().size(), 3u); + + f.AppendLogEventIfNotRepeated(c); + EXPECT_EQ(f.field_log_events().size(), 4u); + f.AppendLogEventIfNotRepeated(c); + EXPECT_EQ(f.field_log_events().size(), 4u); + + f.AppendLogEventIfNotRepeated(a); + EXPECT_EQ(f.field_log_events().size(), 5u); + f.AppendLogEventIfNotRepeated(a); + EXPECT_EQ(f.field_log_events().size(), 5u); +} + } // namespace } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index e392139..75b8b17 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -12,6 +12,7 @@ #include "base/notreached.h" #include "base/ranges/algorithm.h" #include "base/strings/strcat.h" +#include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "components/autofill/core/browser/autofill_browser_util.h" @@ -27,6 +28,7 @@ #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/data_model/iban.h" #include "components/autofill/core/browser/field_filling_address_util.h" +#include "components/autofill/core/browser/field_type_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_parsing/address_field.h" #include "components/autofill/core/browser/form_structure.h" @@ -132,12 +134,69 @@ #endif } +// For a profile containing a full address, the main text is the name, and +// the label is the address. The problem arises when a profile isn't complete +// (aka it doesn't have a name or an address etc.). +// +// `AutofillProfile::CreateDifferentiatingLabels` generates the a text which +// contains 2 address fields. +// +// Example for a full autofill profile: +// "Full Name, Address" +// +// Examples where autofill profiles are incomplete: +// "City, Country" +// "Country, Email" +// +// Note: the separator isn't actually ", ", it is +// IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR +std::u16string GetProfileSuggestionMainTextForNonAddressField( + const AutofillProfile& profile, + const std::string& app_locale) { + std::vector<std::u16string> suggestion_text_array; + AutofillProfile::CreateDifferentiatingLabels({&profile}, app_locale, + &suggestion_text_array); + CHECK_EQ(suggestion_text_array.size(), 1u); + + const std::u16string separator = + l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); + // The first part contains the main text. + return suggestion_text_array[0].substr( + 0, suggestion_text_array[0].find_first_of(separator)); +} + +// Check comment of method above: +// `GetProfileSuggestionMainTextForNonAddressField`. +std::vector<std::u16string> GetProfileSuggestionLabelForNonAddressField( + const std::vector<const AutofillProfile*>& profiles, + const std::string& app_locale) { + std::vector<std::u16string> labels; + AutofillProfile::CreateDifferentiatingLabels(profiles, app_locale, &labels); + CHECK_EQ(labels.size(), profiles.size()); + + for (std::u16string& label : labels) { + const std::u16string separator = + l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); + std::vector<std::u16string> text_pieces = base::SplitStringUsingSubstr( + label, separator, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + // `text_pieces[1]` contains the label. + label = text_pieces.size() > 1 ? text_pieces[1] : u""; + } + return labels; +} + // In addition to just getting the values out of the profile, this function // handles type-specific formatting. std::u16string GetProfileSuggestionMainText( const AutofillProfile& profile, const std::string& app_locale, ServerFieldType trigger_field_type) { + if (!IsAddressType(trigger_field_type) && + base::FeatureList::IsEnabled( + features::kAutofillForUnclassifiedFieldsAvailable)) { + return GetProfileSuggestionMainTextForNonAddressField(profile, app_locale); + } if (trigger_field_type == ADDRESS_HOME_STREET_ADDRESS) { std::string street_address_line; ::i18n::addressinput::GetStreetAddressLinesAsSingleLine( @@ -428,13 +487,19 @@ // Adds footer child suggestions to build autofill popup submenu. void AddFooterChildSuggestions( const AutofillProfile& profile, + ServerFieldType trigger_field_type, absl::optional<ServerFieldTypeSet> last_targeted_fields, Suggestion& suggestion) { + // If the trigger field is not classified as an address field, then the + // filling was triggered from the context menu. In this scenario, the user + // should not be able to fill everything. // If the last filling granularity was not full form, add the // `PopupItemId::kFillEverythingFromAddressProfile` suggestion. This allows // the user to go back to filling the whole form once in a more fine grained // filling experience. - if (!last_targeted_fields || *last_targeted_fields != kAllServerFieldTypes) { + if (IsAddressType(trigger_field_type) && + (!last_targeted_fields || + *last_targeted_fields != kAllServerFieldTypes)) { suggestion.children.push_back(GetFillEverythingFromAddressProfileSuggestion( Suggestion::Guid(profile.guid()))); } @@ -526,18 +591,30 @@ // `last_filling_granularity`. // `last_targeted_fields` specified the last set of fields target by the user. // When not present, we default to full form. +// This function is called only for first-level popup. PopupItemId GetProfileSuggestionPopupItemId( absl::optional<ServerFieldTypeSet> optional_last_targeted_fields, - FieldTypeGroup triggering_field_type_group) { + ServerFieldType trigger_field_type) { if (!base::FeatureList::IsEnabled( features::kAutofillGranularFillingAvailable)) { return PopupItemId::kAddressEntry; } + // If a field is not classified as an address, then autofill was triggered + // from the context menu. + if (!IsAddressType(trigger_field_type) && + base::FeatureList::IsEnabled( + features::kAutofillForUnclassifiedFieldsAvailable)) { + return PopupItemId::kAddressEntryNotSelectable; + } + + const FieldTypeGroup trigger_field_type_group = + GroupTypeOfServerFieldType(trigger_field_type); + // Lambda to return the expected `PopupItemId` when // `optional_last_targeted_fields` matches one of the granular filling groups. auto get_popup_item_id_for_group_filling = [&] { - switch (triggering_field_type_group) { + switch (trigger_field_type_group) { case FieldTypeGroup::kName: return PopupItemId::kFillFullName; case FieldTypeGroup::kAddress: @@ -547,12 +624,16 @@ return PopupItemId::kFillFullPhoneNumber; case FieldTypeGroup::kEmail: return PopupItemId::kFillFullEmail; - default: - // If the 'current_granularity' is group filling, BUT the current - // focused field is not one for which group we offer group filling, - // we default back to fill full form behaviour/pre-granular filling - // popup id. + case FieldTypeGroup::kBirthdateField: return PopupItemId::kAddressEntry; + case FieldTypeGroup::kNoGroup: + case FieldTypeGroup::kCreditCard: + case FieldTypeGroup::kPasswordField: + case FieldTypeGroup::kTransaction: + case FieldTypeGroup::kUsernameField: + case FieldTypeGroup::kUnfillable: + case FieldTypeGroup::kIban: + NOTREACHED_NORETURN(); } }; @@ -686,11 +767,17 @@ // Generate disambiguating labels based on the list of matches. std::vector<std::u16string> differentiating_labels; - if (formatter) { + + if (!IsAddressType(trigger_field_type) && + base::FeatureList::IsEnabled( + features::kAutofillForUnclassifiedFieldsAvailable)) { + differentiating_labels = + GetProfileSuggestionLabelForNonAddressField(profiles, app_locale); + } else if (formatter) { differentiating_labels = formatter->GetLabels(); } else { AutofillProfile::CreateInferredLabels(profiles, field_types, - trigger_field_type, 1, app_locale, + {trigger_field_type}, 1, app_locale, &differentiating_labels); } @@ -1110,7 +1197,7 @@ suggestions.back().acceptance_a11y_announcement = l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_FILLED_FORM); suggestions.back().popup_item_id = GetProfileSuggestionPopupItemId( - last_targeted_fields, trigger_field_type_group); + last_targeted_fields, trigger_field_type); suggestions.back().hidden_prior_to_address_rewriter_usage = previously_hidden_profiles_guid.contains(profile->guid()); if (suggestions.back().popup_item_id == @@ -1312,7 +1399,8 @@ suggestion); AddContactChildSuggestions(trigger_field_type, profile, app_locale, suggestion); - AddFooterChildSuggestions(profile, last_targeted_fields, suggestion); + AddFooterChildSuggestions(profile, trigger_field_type, last_targeted_fields, + suggestion); } std::vector<Suggestion>
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc index 316fdf9..c955b09 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -1393,15 +1393,6 @@ EXPECT_EQ(suggestions[0].icon, Suggestion::Icon::kLocation); } -// Fallback to full form (PopupItemId::kAddressEntry) when the last targeted -// fields are a group but the triggering field does not match any group. -TEST_F(AutofillChildrenSuggestionsGenenarationTest, - CreateSuggestionsFromProfiles_LastTargetedFieldsAreGroup_Fallback) { - std::vector<Suggestion> suggestions = CreateSuggestionWithChildrenFromProfile( - profile(), kAllServerFieldTypes, CREDIT_CARD_TYPE); - EXPECT_EQ(suggestions[0].popup_item_id, PopupItemId::kAddressEntry); -} - // Asserts that when the triggering field is a phone field, the phone number // suggestion is of type `PopupItemId::kFillFullPhoneNumber`. In other // scenarios, phone number is of type `PopupItemId::kAddressFieldByFieldFilling` @@ -1610,6 +1601,179 @@ })); } +class AutofillNonAddressFieldsSuggestionsGenenarationTest + : public AutofillChildrenSuggestionsGenenarationTest { + public: + void SetUp() override { + AutofillChildrenSuggestionsGenenarationTest::SetUp(); + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kAutofillGranularFillingAvailable, + features:: + kAutofillForUnclassifiedFieldsAvailable}, + /*disabled_features=*/{}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(AutofillNonAddressFieldsSuggestionsGenenarationTest, + AllProfilesGenerateSuggestions) { + personal_data()->AddProfile(test::GetFullProfile()); + personal_data()->AddProfile(test::GetFullProfile2()); + + FormFieldData triggering_field; + + EXPECT_EQ(suggestion_generator() + ->GetSuggestionsForProfiles( + {UNKNOWN_TYPE}, triggering_field, UNKNOWN_TYPE, + /*last_targeted_fields=*/absl::nullopt, + AutofillSuggestionTriggerSource::kManualFallbackAddress) + .size(), + 2u); +} + +// Generally, a profile is displayed with name as main text and address as +// label. But with incomplete profiles, it might be problematic. This test +// creates various incomplete profiles and makes sure that a main text and a +// label are always chosen from the available fields (or only main_text if the +// profile has only one field). +TEST_F(AutofillNonAddressFieldsSuggestionsGenenarationTest, + SuggestionsAreCorrectAndExpectedLabelsAreCreated) { + std::vector<AutofillProfile> profiles( + 5, AutofillProfile(i18n_model_definition::kLegacyHierarchyCountryCode)); + profiles[0].SetRawInfo(NAME_FULL, u"test0"); + profiles[0].SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, u"test0_label"); + profiles[1].SetRawInfo(NAME_FULL, u"test1"); + profiles[1].SetRawInfo(ADDRESS_HOME_CITY, u"test1_label"); + profiles[2].SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, u"test2"); + profiles[2].SetRawInfo(ADDRESS_HOME_CITY, u"test2_label"); + profiles[3].SetRawInfo(ADDRESS_HOME_CITY, u"test3"); + profiles[3].SetRawInfo(EMAIL_ADDRESS, u"test3_label"); + profiles[4].SetRawInfo(EMAIL_ADDRESS, u"test4"); + + std::vector<Suggestion> suggestions = + suggestion_generator()->CreateSuggestionsFromProfiles( + {&profiles[0], &profiles[1], &profiles[2], &profiles[3], + &profiles[4]}, + {UNKNOWN_TYPE}, + /*last_targeted_fields=*/absl::nullopt, UNKNOWN_TYPE, + /*trigger_field_max_length=*/0); + + ASSERT_EQ(5u, suggestions.size()); + EXPECT_THAT( + suggestions, + ElementsAre(AllOf(Field(&Suggestion::main_text, + Suggestion::Text( + u"test0", Suggestion::Text::IsPrimary(true))), + Field(&Suggestion::labels, + std::vector<std::vector<Suggestion::Text>>{ + {Suggestion::Text(u"test0_label")}}), + Field(&Suggestion::popup_item_id, + PopupItemId::kAddressEntryNotSelectable)), + AllOf(Field(&Suggestion::main_text, + Suggestion::Text( + u"test1", Suggestion::Text::IsPrimary(true))), + Field(&Suggestion::labels, + std::vector<std::vector<Suggestion::Text>>{ + {Suggestion::Text(u"test1_label")}}), + Field(&Suggestion::popup_item_id, + PopupItemId::kAddressEntryNotSelectable)), + AllOf(Field(&Suggestion::main_text, + Suggestion::Text( + u"test2", Suggestion::Text::IsPrimary(true))), + Field(&Suggestion::labels, + std::vector<std::vector<Suggestion::Text>>{ + {Suggestion::Text(u"test2_label")}}), + Field(&Suggestion::popup_item_id, + PopupItemId::kAddressEntryNotSelectable)), + AllOf(Field(&Suggestion::main_text, + Suggestion::Text( + u"test3", Suggestion::Text::IsPrimary(true))), + Field(&Suggestion::labels, + std::vector<std::vector<Suggestion::Text>>{ + {Suggestion::Text(u"test3_label")}}), + Field(&Suggestion::popup_item_id, + PopupItemId::kAddressEntryNotSelectable)), + AllOf(Field(&Suggestion::main_text, + Suggestion::Text( + u"test4", Suggestion::Text::IsPrimary(true))), + Field(&Suggestion::labels, + std::vector<std::vector<Suggestion::Text>>{{}}), + Field(&Suggestion::popup_item_id, + PopupItemId::kAddressEntryNotSelectable)))); +} + +// Tests that a non-address field suggestion has all the profile fields as +// children, and doesn't have children like "Fill full address" or "Fill full +// name". +TEST_F(AutofillNonAddressFieldsSuggestionsGenenarationTest, + SuggestionHasCorrectChildren) { + std::vector<Suggestion> suggestions = CreateSuggestionWithChildrenFromProfile( + profile(), absl::nullopt, UNKNOWN_TYPE); + + // The child suggestions should be: + // + // 1. first name + // 2. middle name + // 3. family name + // 4. line separator + // 5. address line 1 + // 6. address line 2 + // 7. Zip + // 8. line separator + // 9. phone number + // 10. email + // 11. line separator + // 12. edit address + // 13. delete address + ASSERT_EQ(suggestions.size(), 1u); + ASSERT_EQ(13u, suggestions[0].children.size()); + + EXPECT_THAT( + suggestions[0].children, + ElementsAre( + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(NAME_FIRST, app_locale()), NAME_FIRST, + Suggestion::Guid(profile().guid())), + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(NAME_MIDDLE, app_locale()), NAME_MIDDLE, + Suggestion::Guid(profile().guid())), + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(NAME_LAST, app_locale()), NAME_LAST, + Suggestion::Guid(profile().guid())), + EqualsSuggestion(PopupItemId::kSeparator), + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(ADDRESS_HOME_LINE1, app_locale()), + ADDRESS_HOME_LINE1, Suggestion::Guid(profile().guid())), + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(ADDRESS_HOME_LINE2, app_locale()), + ADDRESS_HOME_LINE2, Suggestion::Guid(profile().guid())), + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(ADDRESS_HOME_ZIP, app_locale()), + ADDRESS_HOME_ZIP, Suggestion::Guid(profile().guid())), + EqualsSuggestion(PopupItemId::kSeparator), + // Triggering field is not a phone number, international phone number + // should be shown to the user. + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + GetFormattedInternationalNumber(), PHONE_HOME_WHOLE_NUMBER, + Suggestion::Guid(profile().guid())), + EqualsFieldByFieldFillingSuggestion( + PopupItemId::kAddressFieldByFieldFilling, + profile().GetInfo(EMAIL_ADDRESS, app_locale()), EMAIL_ADDRESS, + Suggestion::Guid(profile().guid())), + EqualsSuggestion(PopupItemId::kSeparator), + EqualsSuggestion(PopupItemId::kEditAddressProfile), + EqualsSuggestion(PopupItemId::kDeleteAddressProfile))); +} + // TODO(crbug.com/1477646): Investigate AssignLabelsAndDeduplicate and remove // the test if it is not needed. TEST_F(AutofillSuggestionGeneratorTest,
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index cd5df36..c8de60191 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -2019,8 +2019,10 @@ } client().GetCrowdsourcingManager()->StartUploadRequest( - *submitted_form, was_autofilled, non_empty_types, - /*login_form_signature=*/std::string(), observed_submission, + /*upload_contents=*/submitted_form->EncodeUploadRequest( + non_empty_types, was_autofilled, + /*login_form_signature=*/{}, observed_submission), + submitted_form->submission_source(), submitted_form->active_field_count(), client().GetPrefs(), GetWeakPtr()); }
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index 0e7bb972..e2b7a36 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -141,6 +141,10 @@ using ::testing::SaveArg; using ::testing::UnorderedElementsAre; using ::testing::VariantWith; +using upload_contents_matchers::FieldAutofillTypeIs; +using upload_contents_matchers::FieldsAre; +using upload_contents_matchers::FormSignatureIs; +using upload_contents_matchers::ObservedSubmissionIs; const std::string kArbitraryNickname = "Grocery Card"; const std::u16string kArbitraryNickname16 = u"Grocery Card"; @@ -10785,7 +10789,8 @@ BrowserAutofillManagerTest::SetUp(); // All uploads should be expected explicitly. - EXPECT_CALL(*crowdsourcing_manager(), StartUploadRequest).Times(0); + EXPECT_CALL(*crowdsourcing_manager(), StartUploadRequest(_, _, _, _, _)) + .Times(0); form_.name = u"MyForm"; form_.url = GURL("https://myform.com/form.html"); @@ -10813,20 +10818,17 @@ // Ensure that a vote is submitted after a regular form submission. TEST_F(BrowserAutofillManagerVotingTest, Submission) { SimulateTypingFirstNameIntoFirstField(); - - std::map<std::u16string, ServerFieldTypeSet> expected_vote_types = { - {u"firstname", - {ServerFieldType::NAME_FIRST, ServerFieldType::CREDIT_CARD_NAME_FIRST}}, - {u"lastname", {ServerFieldType::EMPTY_TYPE}}, - }; - - // Ensure that vote is submitted after form submission. EXPECT_CALL( *crowdsourcing_manager(), - StartUploadRequest(AllOf(SignatureIs(CalculateFormSignature(form_)), - UploadedAutofillTypesAre(expected_vote_types)), - _, _, _, /*observed_submission=*/true, _, _)) - .Times(1); + StartUploadRequest( + FirstElementIs(AllOf( + FormSignatureIs(CalculateFormSignature(form_)), + FieldsAre(FieldAutofillTypeIs( + {ServerFieldType::NAME_FIRST, + ServerFieldType::CREDIT_CARD_NAME_FIRST}), + FieldAutofillTypeIs({ServerFieldType::EMPTY_TYPE})), + ObservedSubmissionIs(true))), + _, _, _, _)); FormSubmitted(form_); } @@ -10847,19 +10849,19 @@ // 4. Simulate removing the focus from the form, which generates a second blur // vote which should be sent. - std::map<std::u16string, ServerFieldTypeSet> expected_vote_types = { - {u"firstname", - {ServerFieldType::NAME_FIRST, ServerFieldType::CREDIT_CARD_NAME_FIRST}}, - {u"lastname", - {ServerFieldType::NAME_LAST, ServerFieldType::CREDIT_CARD_NAME_LAST, - ServerFieldType::NAME_LAST_SECOND}}, - }; - EXPECT_CALL( - *crowdsourcing_manager(), - StartUploadRequest(AllOf(SignatureIs(first_form_signature), - UploadedAutofillTypesAre(expected_vote_types)), - _, _, _, /*observed_submission=*/false, _, _)) - .Times(1); + EXPECT_CALL(*crowdsourcing_manager(), + StartUploadRequest( + FirstElementIs(AllOf( + FormSignatureIs(first_form_signature), + FieldsAre(FieldAutofillTypeIs( + {ServerFieldType::NAME_FIRST, + ServerFieldType::CREDIT_CARD_NAME_FIRST}), + FieldAutofillTypeIs( + {ServerFieldType::NAME_LAST, + ServerFieldType::CREDIT_CARD_NAME_LAST, + ServerFieldType::NAME_LAST_SECOND})), + ObservedSubmissionIs(false))), + _, _, _, _)); browser_autofill_manager_->OnFocusNoLongerOnForm(true); // 5. Grow the form by one field, which changes the form signature. @@ -10873,19 +10875,18 @@ EXPECT_NE(first_form_signature, second_form_signature); // Because the next field after the two names is not a credit card field, // field disambiguation removes the credit card name votes. - expected_vote_types = { - {u"firstname", {ServerFieldType::NAME_FIRST}}, - {u"lastname", - {ServerFieldType::NAME_LAST, ServerFieldType::NAME_LAST_SECOND}}, - {u"zip", {ServerFieldType::EMPTY_TYPE}}, - }; EXPECT_CALL( *crowdsourcing_manager(), - StartUploadRequest(AllOf(SignatureIs(second_form_signature), - UploadedAutofillTypesAre(expected_vote_types)), - _, _, _, - /*observed_submission=*/true, _, _)) - .Times(1); + StartUploadRequest( + FirstElementIs(AllOf( + FormSignatureIs(second_form_signature), + FieldsAre( + FieldAutofillTypeIs({ServerFieldType::NAME_FIRST}), + FieldAutofillTypeIs({ServerFieldType::NAME_LAST, + ServerFieldType::NAME_LAST_SECOND}), + FieldAutofillTypeIs({ServerFieldType::EMPTY_TYPE})), + ObservedSubmissionIs(true))), + _, _, _, _)); FormSubmitted(form_); } @@ -10894,17 +10895,17 @@ SimulateTypingFirstNameIntoFirstField(); // Simulate removing focus from form, which triggers a blur vote. - std::map<std::u16string, ServerFieldTypeSet> expected_vote_types = { - {u"firstname", - {ServerFieldType::NAME_FIRST, ServerFieldType::CREDIT_CARD_NAME_FIRST}}, - {u"lastname", {ServerFieldType::EMPTY_TYPE}}, - }; EXPECT_CALL( *crowdsourcing_manager(), - StartUploadRequest(AllOf(SignatureIs(CalculateFormSignature(form_)), - UploadedAutofillTypesAre(expected_vote_types)), - _, _, _, /*observed_submission=*/false, _, _)) - .Times(1); + StartUploadRequest( + FirstElementIs(AllOf( + FormSignatureIs(CalculateFormSignature(form_)), + FieldsAre(FieldAutofillTypeIs( + {ServerFieldType::NAME_FIRST, + ServerFieldType::CREDIT_CARD_NAME_FIRST}), + FieldAutofillTypeIs({ServerFieldType::EMPTY_TYPE})), + ObservedSubmissionIs(false))), + _, _, _, _)); browser_autofill_manager_->OnFocusNoLongerOnForm(true); // Simulate a navigation. This is when the vote is sent. @@ -10916,22 +10917,20 @@ TEST_F(BrowserAutofillManagerVotingTest, NoBlurVoteOnSubmission) { SimulateTypingFirstNameIntoFirstField(); - std::map<std::u16string, ServerFieldTypeSet> expected_vote_types = { - {u"firstname", - {ServerFieldType::NAME_FIRST, ServerFieldType::CREDIT_CARD_NAME_FIRST}}, - {u"lastname", {ServerFieldType::EMPTY_TYPE}}, - }; - // Simulate removing focus from form, which enqueues a blur vote. The blur // vote will be ignored and only the submission will be sent. browser_autofill_manager_->OnFocusNoLongerOnForm(true); - EXPECT_CALL( *crowdsourcing_manager(), - StartUploadRequest(AllOf(SignatureIs(CalculateFormSignature(form_)), - UploadedAutofillTypesAre(expected_vote_types)), - _, _, _, /*observed_submission=*/true, _, _)) - .Times(1); + StartUploadRequest( + FirstElementIs(AllOf( + FormSignatureIs(CalculateFormSignature(form_)), + FieldsAre(FieldAutofillTypeIs( + {ServerFieldType::NAME_FIRST, + ServerFieldType::CREDIT_CARD_NAME_FIRST}), + FieldAutofillTypeIs({ServerFieldType::EMPTY_TYPE})), + ObservedSubmissionIs(true))), + _, _, _, _)); FormSubmitted(form_); }
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h index 3f033501..16af6d7 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h
@@ -18,6 +18,7 @@ #include "base/time/time.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" #include "components/version_info/channel.h" #include "net/base/backoff_entry.h"
diff --git a/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h b/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h index a7d9d6d..7eb8cde 100644 --- a/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h +++ b/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h
@@ -34,6 +34,15 @@ MOCK_METHOD(bool, StartUploadRequest, + (std::vector<AutofillUploadContents>, + mojom::SubmissionSource, + int, + PrefService*, + base::WeakPtr<Observer>), + (override)); + + MOCK_METHOD(bool, + StartUploadRequest, (const FormStructure&, bool, const ServerFieldTypeSet&,
diff --git a/components/autofill/core/browser/data_model/autofill_profile.cc b/components/autofill/core/browser/data_model/autofill_profile.cc index a4866058..b52f448 100644 --- a/components/autofill/core/browser/data_model/autofill_profile.cc +++ b/components/autofill/core/browser/data_model/autofill_profile.cc
@@ -150,16 +150,16 @@ return SpecificityForType(type1) < SpecificityForType(type2); } -// Fills |distinguishing_fields| with a list of fields to use when creating +// Fills `distinguishing_fields` with a list of fields to use when creating // labels that can help to distinguish between two profiles. Draws fields from -// |suggested_fields| if it is non-NULL; otherwise returns a default list. -// If |suggested_fields| is non-NULL, does not include |excluded_field| in the -// list. Otherwise, |excluded_field| is ignored, and should be set to -// |UNKNOWN_TYPE| by convention. The resulting list of fields is sorted in +// `suggested_fields` if it is non-NULL; otherwise returns a default list. +// If `suggested_fields` is non-NULL, does not include `excluded_fields` in the +// list. Otherwise, `excluded_fields` is ignored, and should be set to +// an empty list by convention. The resulting list of fields is sorted in // decreasing order of importance. void GetFieldsForDistinguishingProfiles( const std::vector<ServerFieldType>* suggested_fields, - ServerFieldType excluded_field, + ServerFieldTypeSet excluded_fields, std::vector<ServerFieldType>* distinguishing_fields) { static const ServerFieldType kDefaultDistinguishingFields[] = { NAME_FULL, @@ -181,7 +181,7 @@ default_fields.assign( kDefaultDistinguishingFields, kDefaultDistinguishingFields + std::size(kDefaultDistinguishingFields)); - if (excluded_field == UNKNOWN_TYPE) { + if (excluded_fields.empty()) { distinguishing_fields->swap(default_fields); return; } @@ -189,10 +189,12 @@ } // Keep track of which fields we've seen so that we avoid duplicate entries. - // Always ignore fields of unknown type and the excluded field. + // Always ignore fields of unknown type and those part of `excluded_fields`. ServerFieldTypeSet seen_fields; seen_fields.insert(UNKNOWN_TYPE); - seen_fields.insert(GetStorableTypeCollapsingGroups(excluded_field)); + for (ServerFieldType excluded_field : excluded_fields) { + seen_fields.insert(GetStorableTypeCollapsingGroups(excluded_field)); + } distinguishing_fields->clear(); for (const ServerFieldType& it : *suggested_fields) { @@ -204,13 +206,18 @@ std::sort(distinguishing_fields->begin(), distinguishing_fields->end(), CompareSpecificity); - // Special case: If the excluded field is a partial name (e.g. first name) and - // the suggested fields include other name fields, include |NAME_FULL| in the - // list of distinguishing fields as a last-ditch fallback. This allows us to - // distinguish between profiles that are identical except for the name. - ServerFieldType effective_excluded_type = - GetStorableTypeCollapsingGroups(excluded_field); - if (excluded_field != effective_excluded_type) { + // Special case: If one of the excluded fields is a partial name (e.g. + // `NAME_FIRST`) or phone number (e.g `PHONE_HOME_CITY_CODE`) and the + // suggested fields include other name or phone fields fields, include + // `NAME_FULL` or `PHONE_HOME_WHOLE_NUMBER` in the list of distinguishing + // fields as a last-ditch fallback. This allows us to distinguish between + // profiles that are identical except for the name or phone number. + for (ServerFieldType excluded_field : excluded_fields) { + ServerFieldType effective_excluded_type = + GetStorableTypeCollapsingGroups(excluded_field); + if (excluded_field == effective_excluded_type) { + continue; + } for (const ServerFieldType& it : *suggested_fields) { if (it != excluded_field && GetStorableTypeCollapsingGroups(it) == effective_excluded_type) { @@ -885,8 +892,8 @@ const std::string& app_locale, std::vector<std::u16string>* labels) { const size_t kMinimalFieldsShown = 2; - CreateInferredLabels(profiles, absl::nullopt, UNKNOWN_TYPE, - kMinimalFieldsShown, app_locale, labels); + CreateInferredLabels(profiles, absl::nullopt, {}, kMinimalFieldsShown, + app_locale, labels); DCHECK_EQ(profiles.size(), labels->size()); } @@ -894,7 +901,7 @@ void AutofillProfile::CreateInferredLabels( const std::vector<const AutofillProfile*>& profiles, const absl::optional<ServerFieldTypeSet>& suggested_fields, - ServerFieldType excluded_field, + ServerFieldTypeSet excluded_fields, size_t minimal_fields_shown, const std::string& app_locale, std::vector<std::u16string>* labels) { @@ -904,7 +911,7 @@ ? std::vector(suggested_fields->begin(), suggested_fields->end()) : std::vector<ServerFieldType>(); GetFieldsForDistinguishingProfiles( - suggested_fields ? &suggested_fields_types : nullptr, excluded_field, + suggested_fields ? &suggested_fields_types : nullptr, excluded_fields, &fields_to_use); // Construct the default label for each profile. Also construct a map that
diff --git a/components/autofill/core/browser/data_model/autofill_profile.h b/components/autofill/core/browser/data_model/autofill_profile.h index 4304b724..c1a404a 100644 --- a/components/autofill/core/browser/data_model/autofill_profile.h +++ b/components/autofill/core/browser/data_model/autofill_profile.h
@@ -198,17 +198,17 @@ const std::string& app_locale, std::vector<std::u16string>* labels); - // Creates inferred labels for |profiles|, according to the rules above and - // stores them in |created_labels|. If |suggested_fields| is not NULL, the - // resulting label fields are drawn from |suggested_fields|, except excluding - // |excluded_field|. Otherwise, the label fields are drawn from a default set, - // and |excluded_field| is ignored; by convention, it should be of - // |UNKNOWN_TYPE| when |suggested_fields| is NULL. Each label includes at - // least |minimal_fields_shown| fields, if possible. + // Creates inferred labels for `profiles`, according to the rules above and + // stores them in `labels`. If `suggested_fields` is not nullopt, the + // resulting label fields are drawn from it minus those in + // `excluded_fields`. Otherwise, the label fields are drawn from a default + // set, and `excluded_fields` are ignored; by convention, it should be + // an empty set when `suggested_fields` is nullopt. Each label includes at + // least `minimal_fields_shown` fields, if possible. static void CreateInferredLabels( const std::vector<const AutofillProfile*>& profiles, const absl::optional<ServerFieldTypeSet>& suggested_fields, - ServerFieldType excluded_field, + ServerFieldTypeSet excluded_fields, size_t minimal_fields_shown, const std::string& app_locale, std::vector<std::u16string>* labels);
diff --git a/components/autofill/core/browser/data_model/autofill_profile_unittest.cc b/components/autofill/core/browser/data_model/autofill_profile_unittest.cc index 8a230b90..d147bac2 100644 --- a/components/autofill/core/browser/data_model/autofill_profile_unittest.cc +++ b/components/autofill/core/browser/data_model/autofill_profile_unittest.cc
@@ -289,9 +289,8 @@ std::vector<std::u16string> labels; for (size_t i = 0; i < std::size(kExpectedLabels); ++i) { - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, i, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), absl::nullopt, {}, i, "en-US", &labels); ASSERT_FALSE(labels.empty()); EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back()); } @@ -324,9 +323,8 @@ std::vector<std::u16string> labels; for (size_t i = 0; i < std::size(kExpectedLabels); ++i) { - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, i, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), absl::nullopt, {}, i, "en-US", &labels); ASSERT_FALSE(labels.empty()); EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back()); } @@ -369,9 +367,8 @@ std::vector<std::u16string> labels; for (size_t i = 0; i < std::size(kExpectedLabels); ++i) { - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, i, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), absl::nullopt, {}, i, "en-US", &labels); ASSERT_FALSE(labels.empty()); EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back()); } @@ -407,9 +404,8 @@ std::vector<std::u16string> labels; for (size_t i = 0; i < std::size(kExpectedLabels); ++i) { - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, i, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), absl::nullopt, {}, i, "en-US", &labels); ASSERT_FALSE(labels.empty()); EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back()); } @@ -441,9 +437,8 @@ std::vector<std::u16string> labels; for (size_t i = 0; i < std::size(kExpectedLabels); ++i) { - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, i, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), absl::nullopt, {}, i, "en-US", &labels); ASSERT_FALSE(labels.empty()); EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back()); } @@ -464,15 +459,13 @@ std::vector<std::u16string> labels; // Two fields at least - no filter. AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, 2, "en-US", - &labels); + absl::nullopt, {}, 2, "en-US", &labels); EXPECT_EQ(u"John Doe, 666 Erebus St.", labels[0]); EXPECT_EQ(u"Jane Doe, 123 Letha Shore.", labels[1]); // Three fields at least - no filter. AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, 3, "en-US", - &labels); + absl::nullopt, {}, 3, "en-US", &labels); EXPECT_EQ(u"John Doe, 666 Erebus St., Elysium", labels[0]); EXPECT_EQ(u"Jane Doe, 123 Letha Shore., Dis", labels[1]); @@ -480,23 +473,21 @@ ADDRESS_HOME_ZIP}; // Two fields at least, from suggested fields - no filter. - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, UNKNOWN_TYPE, 2, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), suggested_fields, {}, 2, "en-US", &labels); EXPECT_EQ(u"Elysium 91111", labels[0]); EXPECT_EQ(u"Dis 91222", labels[1]); // Three fields at least, from suggested fields - no filter. - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, UNKNOWN_TYPE, 3, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), suggested_fields, {}, 3, "en-US", &labels); EXPECT_EQ(u"Elysium, CA 91111", labels[0]); EXPECT_EQ(u"Dis, CA 91222", labels[1]); // Three fields at least, from suggested fields - but filter reduces available // fields to two. AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, ADDRESS_HOME_ZIP, 3, + suggested_fields, {ADDRESS_HOME_ZIP}, 3, "en-US", &labels); EXPECT_EQ(u"Elysium, CA", labels[0]); EXPECT_EQ(u"Dis, CA", labels[1]); @@ -504,16 +495,15 @@ // In our implementation we always display NAME_FULL for all NAME* fields... suggested_fields = {NAME_MIDDLE}; // One field at least, from suggested fields - no filter. - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, UNKNOWN_TYPE, 1, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), suggested_fields, {}, 1, "en-US", &labels); EXPECT_EQ(u"John Doe", labels[0]); EXPECT_EQ(u"Jane Doe", labels[1]); // One field at least, from suggested fields - filter the same as suggested // field. AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, NAME_MIDDLE, 1, + suggested_fields, {NAME_MIDDLE}, 1, "en-US", &labels); EXPECT_EQ(std::u16string(), labels[0]); EXPECT_EQ(std::u16string(), labels[1]); @@ -521,9 +511,8 @@ // In our implementation we always display NAME_FULL for NAME_MIDDLE_INITIAL suggested_fields = {NAME_MIDDLE}; // One field at least, from suggested fields - no filter. - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, UNKNOWN_TYPE, 1, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), suggested_fields, {}, 1, "en-US", &labels); EXPECT_EQ(u"John Doe", labels[0]); EXPECT_EQ(u"Jane Doe", labels[1]); @@ -531,14 +520,14 @@ // unknown suggested field. suggested_fields = {UNKNOWN_TYPE, NAME_FULL, ADDRESS_HOME_LINE1}; AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, NAME_FULL, 1, "en-US", - &labels); + suggested_fields, {NAME_FULL}, 1, + "en-US", &labels); EXPECT_EQ(std::u16string(u"666 Erebus St."), labels[0]); EXPECT_EQ(std::u16string(u"123 Letha Shore."), labels[1]); // No suggested fields, but non-unknown excluded field. AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, NAME_FULL, 1, "en-US", + absl::nullopt, {NAME_FULL}, 1, "en-US", &labels); EXPECT_EQ(std::u16string(u"666 Erebus St."), labels[0]); EXPECT_EQ(std::u16string(u"123 Letha Shore."), labels[1]); @@ -564,8 +553,8 @@ EMAIL_ADDRESS}; std::vector<std::u16string> labels; AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, NAME_LAST, 1, "en-US", - &labels); + suggested_fields, {NAME_LAST}, 1, + "en-US", &labels); ASSERT_EQ(2U, labels.size()); EXPECT_EQ(u"88 Nowhere Ave.", labels[0]); EXPECT_EQ(u"88 Nowhere Ave.", labels[1]); @@ -573,8 +562,8 @@ // Otherwise, we should. suggested_fields.insert(NAME_FIRST); AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, NAME_LAST, 1, "en-US", - &labels); + suggested_fields, {NAME_LAST}, 1, + "en-US", &labels); ASSERT_EQ(2U, labels.size()); EXPECT_EQ(u"88 Nowhere Ave., John Doe", labels[0]); EXPECT_EQ(u"88 Nowhere Ave., Johnny K Doe", labels[1]); @@ -596,9 +585,8 @@ // should not fall back to the full name as a distinguishing field. ServerFieldTypeSet suggested_fields = {ADDRESS_HOME_LINE1, EMAIL_ADDRESS}; std::vector<std::u16string> labels; - AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, UNKNOWN_TYPE, 2, - "en-US", &labels); + AutofillProfile::CreateInferredLabels( + ToRawPointerVector(profiles), suggested_fields, {}, 2, "en-US", &labels); ASSERT_EQ(2U, labels.size()); EXPECT_EQ(u"88 Nowhere Ave., doe@example.com", labels[0]); EXPECT_EQ(u"88 Nowhere Ave., dojo@example.com", labels[1]); @@ -623,8 +611,7 @@ std::vector<std::u16string> labels; AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, 3, "en-US", - &labels); + absl::nullopt, {}, 3, "en-US", &labels); ASSERT_EQ(3U, labels.size()); EXPECT_EQ(u"John Doe, doe@example.com, Gogole", labels[0]); EXPECT_EQ(u"John Doe, doe@example.com, Ggoole", labels[1]); @@ -634,8 +621,7 @@ // distinguishing field. profiles[1]->SetRawInfo(ADDRESS_HOME_LINE1, u"88 Nowhere Ave."); AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - absl::nullopt, UNKNOWN_TYPE, 1, "en-US", - &labels); + absl::nullopt, {}, 1, "en-US", &labels); ASSERT_EQ(3U, labels.size()); EXPECT_EQ(u"John Doe, doe@example.com, Gogole", labels[0]); EXPECT_EQ(u"John Doe, 88 Nowhere Ave., doe@example.com, Ggoole", labels[1]) @@ -657,8 +643,8 @@ ADDRESS_HOME_STREET_ADDRESS}; std::vector<std::u16string> labels; AutofillProfile::CreateInferredLabels(ToRawPointerVector(profiles), - suggested_fields, NAME_FULL, 1, "en-US", - &labels); + suggested_fields, {NAME_FULL}, 1, + "en-US", &labels); ASSERT_EQ(1U, labels.size()); EXPECT_EQ(u"88 Nowhere Ave., Apt. 42", labels[0]); }
diff --git a/components/autofill/core/browser/metrics/log_event.cc b/components/autofill/core/browser/metrics/log_event.cc index 96cef8d..07ba8901 100644 --- a/components/autofill/core/browser/metrics/log_event.cc +++ b/components/autofill/core/browser/metrics/log_event.cc
@@ -53,12 +53,12 @@ bool AreCollapsible(const TriggerFillFieldLogEvent& event1, const TriggerFillFieldLogEvent& event2) { - return event1.fill_event_id != event2.fill_event_id; + return event1.fill_event_id == event2.fill_event_id; } bool AreCollapsible(const FillFieldLogEvent& event1, const FillFieldLogEvent& event2) { - return event1.fill_event_id != event2.fill_event_id && + return event1.fill_event_id == event2.fill_event_id && event1.had_value_before_filling == event2.had_value_before_filling && event1.autofill_skipped_status == event2.autofill_skipped_status && event1.was_autofilled == event2.was_autofilled &&
diff --git a/components/autofill/core/browser/metrics/log_event.h b/components/autofill/core/browser/metrics/log_event.h index 82bb426..1f601f8 100644 --- a/components/autofill/core/browser/metrics/log_event.h +++ b/components/autofill/core/browser/metrics/log_event.h
@@ -95,7 +95,7 @@ // Log the field that triggers the suggestion that the user selects to fill. struct TriggerFillFieldLogEvent { FillEventId fill_event_id = GetNextFillEventId(); - // The type of filled data for the autofil event. + // The type of filled data for the Autofill event. FillDataType data_type = internal::IsRequired(); // The country_code associated with the information filled. Only present for // autofill addresses (i.e. `AutofillEventType::kAutofillProfile`).
diff --git a/components/autofill/core/browser/profile_token_quality.cc b/components/autofill/core/browser/profile_token_quality.cc index 837b13a0..b3d70507 100644 --- a/components/autofill/core/browser/profile_token_quality.cc +++ b/components/autofill/core/browser/profile_token_quality.cc
@@ -147,9 +147,19 @@ // The field was not autofilled or autofilled with a different profile. continue; } + if (!field.autofilled_type()) { + // TODO(b/311604770): Field-by-field filling doesn't support + // `autofilled_type()`. + continue; + } + if (!GetSupportedTypes(*profile_).contains(*field.autofilled_type())) { + // If the user changed the country of their profile before submission, the + // `autofilled_type()` might not be supported anymore. + continue; + } const ServerFieldType stored_type = - profile_->GetStorableTypeOf(field.Type().GetStorableType()); + profile_->GetStorableTypeOf(*field.autofilled_type()); const FormSignatureHash hash = GetFormSignatureHash(form_structure.form_signature()); if (auto observations = observations_.find(stored_type); @@ -202,7 +212,6 @@ std::vector<ObservationType> ProfileTokenQuality::GetObservationTypesForFieldType( ServerFieldType type) const { - CHECK(GetSupportedTypes(*profile_).contains(type)); const auto it = observations_.find(profile_->GetStorableTypeOf(type)); if (it == observations_.end()) { return {};
diff --git a/components/autofill/core/browser/profile_token_quality_unittest.cc b/components/autofill/core/browser/profile_token_quality_unittest.cc index e371ad2..f7927537 100644 --- a/components/autofill/core/browser/profile_token_quality_unittest.cc +++ b/components/autofill/core/browser/profile_token_quality_unittest.cc
@@ -221,6 +221,24 @@ UnorderedElementsAre(ObservationType::kAccepted)); } +// Tests that when the type of a field changes between filling and submission, +// observations are collected for the type the field had when it was filled. +TEST_F(ProfileTokenQualityTest, AddObservationsForFilledForm_DynamicChange) { + AutofillProfile profile = test::GetFullProfile(); + pdm_.AddProfile(profile); + ProfileTokenQuality& quality = profile.token_quality(); + + FormData form = GetFormWithTypes({NAME_FIRST}); + FillForm(form, profile); + + FormStructure* form_structure = bam_.FindCachedFormById(form.global_id()); + form_structure->field(0)->SetTypeTo(AutofillType(NAME_LAST)); + EXPECT_TRUE( + quality.AddObservationsForFilledForm(*form_structure, form, pdm_)); + EXPECT_THAT(quality.GetObservationTypesForFieldType(NAME_FIRST), + UnorderedElementsAre(ObservationType::kAccepted)); +} + // Tests that `SaveObservationsForFilledFormForAllSubmittedProfiles()` collects // observations for all profiles that were used to fill the form. TEST_F(ProfileTokenQualityTest,
diff --git a/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h b/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h index 3ac8683..8a61dc6 100644 --- a/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h +++ b/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h
@@ -12,6 +12,7 @@ #include "base/strings/string_number_conversions.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/form_structure_test_api.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,6 +26,56 @@ using ::testing::Property; using ::testing::ResultOf; +// Returns a container matcher that applies `matcher` to the first element of +// the container. +inline auto FirstElementIs(auto matcher) { + return ::testing::AllOf( + ::testing::SizeIs(::testing::Gt(0u)), + ResultOf([](const auto& container) { return container[0]; }, matcher)); +} + +// Matchers for `AutofillUploadContents`. These are in their own namespace to +// make their names briefer. +namespace upload_contents_matchers { + +// Creates a matcher for an `AutofillUploadContents`'s form_signature method +// against `form_signature`. +inline ::testing::Matcher<AutofillUploadContents> FormSignatureIs( + FormSignature form_signature) { + return Property("form_signature", &AutofillUploadContents::form_signature, + form_signature.value()); +} + +// Creates a matcher that matches `matchers` against the fields of an +// `AutofillUploadContents`. It requires that the match (and ordering) is exact. +template <typename... Matchers> +inline ::testing::Matcher<AutofillUploadContents> FieldsAre( + Matchers... matchers) { + return ::testing::Property("field", &AutofillUploadContents::field, + ::testing::ElementsAre(matchers...)); +} + +inline ::testing::Matcher<AutofillUploadContents> ObservedSubmissionIs( + bool observed_submission) { + return ::testing::Property("submission", &AutofillUploadContents::submission, + observed_submission); +} + +// Matchers for `AutofillUploadContents::Field`. +inline ::testing::Matcher<AutofillUploadContents::Field> FieldAutofillTypeIs( + ServerFieldTypeSet type_set) { + auto extract_types = [](const AutofillUploadContents::Field& field) { + ServerFieldTypeSet s; + for (auto type : field.autofill_type()) { + s.insert(ToSafeServerFieldType(type, ServerFieldType::NO_SERVER_DATA)); + } + return s; + }; + return ::testing::ResultOf(extract_types, ::testing::Eq(type_set)); +} + +} // namespace upload_contents_matchers + inline auto SignatureIsSameAs(const FormData& form) { return Property("form_signature", &FormStructure::form_signature, CalculateFormSignature(form));
diff --git a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapper.java b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapper.java index eda8791e..c2684f85 100644 --- a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapper.java +++ b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/NotificationWrapper.java
@@ -26,7 +26,8 @@ /** * Gets the notification metadata. - * @See {@link NotificationMetadata}. + * + * @see {@link NotificationMetadata}. */ public NotificationMetadata getMetadata() { return mNotificationMetadata;
diff --git a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/PendingIntentProvider.java b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/PendingIntentProvider.java index bb35def..85537b020 100644 --- a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/PendingIntentProvider.java +++ b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/PendingIntentProvider.java
@@ -20,7 +20,8 @@ /** * Creates {@link PendingIntent}that triggers {@link android.content.BroadcastReceiver}. - * @See {@link PendingIntent#getBroadcast(Context, int, Intent, int)}. + * + * @see {@link PendingIntent#getBroadcast(Context, int, Intent, int)}. */ public static PendingIntentProvider getBroadcast( Context context, int requestCode, Intent intent, int flags, boolean mutable) { @@ -39,7 +40,8 @@ /** * Creates {@link PendingIntent} that triggers {@link android.app.Service}. - * @See {@link PendingIntent#getService(Context, int, Intent, int)} . + * + * @see {@link PendingIntent#getService(Context, int, Intent, int)} . */ public static PendingIntentProvider getService( Context context, int requestCode, Intent intent, int flags, boolean mutable) { @@ -56,7 +58,8 @@ /** * Creates {@link PendingIntent} that triggers {@link android.app.Activity}. - * @See {@link PendingIntent#getActivity(Context, int, Intent, int)}. + * + * @see {@link PendingIntent#getActivity(Context, int, Intent, int)}. */ public static PendingIntentProvider getActivity( Context context, int requestCode, Intent intent, int flags, boolean mutable) {
diff --git a/components/content_capture/android/java/src/org/chromium/components/content_capture/PlatformContentCaptureConsumer.java b/components/content_capture/android/java/src/org/chromium/components/content_capture/PlatformContentCaptureConsumer.java index 1c898c9b..7e22e02 100644 --- a/components/content_capture/android/java/src/org/chromium/components/content_capture/PlatformContentCaptureConsumer.java +++ b/components/content_capture/android/java/src/org/chromium/components/content_capture/PlatformContentCaptureConsumer.java
@@ -26,8 +26,8 @@ /** * This method is used when ViewStructure is available. * - * @Return ContentCaptureConsumer or null if ContentCapture service isn't - * available, disabled or isn't AiAi service. + * @return ContentCaptureConsumer or null if ContentCapture service isn't available, disabled or + * isn't AiAi service. */ public static ContentCaptureConsumer create( Context context, View view, ViewStructure structure, WebContents webContents) {
diff --git a/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java b/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java index 15441565..61c9a14b 100644 --- a/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java +++ b/components/image_fetcher/android/java/src/org/chromium/components/image_fetcher/ImageFetcher.java
@@ -45,7 +45,8 @@ /** * Creates image fetcher parameters. The image will not be resized. - * @See {@link #Params(String, String, int, int, boolean, int)}. + * + * @see {@link #Params(String, String, int, int, boolean, int)}. */ public static Params create(final GURL url, String clientName) { return create(url.getSpec(), clientName); @@ -53,7 +54,8 @@ /** * Creates image fetcher parameters. The image will not be resized. - * @See {@link #Params(String, String, int, int, boolean, int)}. + * + * @see {@link #Params(String, String, int, int, boolean, int)}. */ @Deprecated public static Params create(final String url, String clientName) { @@ -63,7 +65,8 @@ /** * Creates image fetcher parameters with image size specified. - * @See {@link #Params(String, String, int, int, boolean, int)}. + * + * @see {@link #Params(String, String, int, int, boolean, int)}. */ public static Params create(final GURL url, String clientName, int width, int height) { return create(url.getSpec(), clientName, width, height); @@ -71,7 +74,8 @@ /** * Creates image fetcher parameters with image size specified. - * @See {@link #Params(String, String, int, int, boolean, int)}. + * + * @see {@link #Params(String, String, int, int, boolean, int)}. */ @Deprecated public static Params create(final String url, String clientName, int width, int height) { @@ -82,7 +86,8 @@ /** * Creates image fetcher parameters with image size specified. - * @See {@link #Params(String, String, int, int, boolean, int)}. + * + * @see {@link #Params(String, String, int, int, boolean, int)}. */ public static Params createNoResizing( final GURL url, String clientName, int width, int height) { @@ -98,7 +103,8 @@ /** * Only used in rare cases. Creates image fetcher parameters that keeps the cache file for a * certain period of time. - * @See {@link #Params(String, String, int, int, boolean, int)}. + * + * @see {@link #Params(String, String, int, int, boolean, int)}. */ public static Params createWithExpirationInterval( final GURL url,
diff --git a/components/password_manager/core/browser/affiliation/affiliation_utils.cc b/components/password_manager/core/browser/affiliation/affiliation_utils.cc index 8152881e..bc541b2 100644 --- a/components/password_manager/core/browser/affiliation/affiliation_utils.cc +++ b/components/password_manager/core/browser/affiliation/affiliation_utils.cc
@@ -55,7 +55,7 @@ url::StdStringCanonOutput canonical_output(canonical_uri); bool canonicalization_succeeded = url::CanonicalizeStandardURL( - input_uri.c_str(), input_uri.size(), input_parsed, + input_uri.c_str(), input_parsed, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &canonical_output, &canonical_parsed); canonical_output.Complete();
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index cc71322..147d3d4 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -438,7 +438,8 @@ ON_CALL(*client_.GetPasswordFeatureManager(), ShouldShowAccountStorageBubbleUi) .WillByDefault(Return(true)); - ON_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + ON_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .WillByDefault(Return(true)); ON_CALL(*client_.GetPasswordFeatureManager(), GetDefaultPasswordStore) .WillByDefault(Return(PasswordForm::Store::kProfileStore)); @@ -3327,7 +3328,8 @@ ServerFieldTypeSet{NOT_USERNAME}, _, true, nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID)
diff --git a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc index 64b24f4d..7e6de17 100644 --- a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc +++ b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
@@ -281,7 +281,8 @@ ON_CALL(client_, GetAutofillCrowdsourcingManager()) .WillByDefault(Return(&mock_autofill_crowdsourcing_manager_)); - ON_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + ON_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .WillByDefault(Return(true)); ON_CALL(*client_.GetPasswordFeatureManager(), GetDefaultPasswordStore) .WillByDefault(Return(PasswordForm::Store::kProfileStore)); @@ -891,7 +892,8 @@ // TODO(https://crbug.com/928690): implement not sending incorrect votes and // check that StartUploadRequest is not called. - EXPECT_CALL(*mock_autofill_crowdsourcing_manager(), StartUploadRequest) + EXPECT_CALL(*mock_autofill_crowdsourcing_manager(), + StartUploadRequest(_, _, _, _, _, _, _)) .Times(1); password_save_manager_impl()->Save(&observed_form_, parsed_submitted_form); }
diff --git a/components/password_manager/core/browser/votes_uploader_unittest.cc b/components/password_manager/core/browser/votes_uploader_unittest.cc index bdc52661..ccf94aa 100644 --- a/components/password_manager/core/browser/votes_uploader_unittest.cc +++ b/components/password_manager/core/browser/votes_uploader_unittest.cc
@@ -105,7 +105,8 @@ EXPECT_CALL(client_, GetAutofillCrowdsourcingManager()) .WillRepeatedly(Return(&mock_autofill_crowdsourcing_manager_)); - ON_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + ON_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .WillByDefault(Return(true)); // Create |fields| in |form_to_upload_| and |submitted_form_|. Only |name| @@ -259,7 +260,8 @@ // SendVotesOnSave should call UploadPasswordVote and StartUploadRequest // twice. The first call is not the one that should be tested. testing::Expectation first_call = - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest); + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)); EXPECT_CALL( mock_autofill_crowdsourcing_manager_, @@ -636,7 +638,8 @@ TEST_F(VotesUploaderTest, NoSingleUsernameDataNoUpload) { VotesUploader votes_uploader(&client_, false); - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); base::HistogramTester histogram_tester; votes_uploader.set_should_send_username_first_flow_votes(true); @@ -688,7 +691,8 @@ false, expected_types, std::string(), true, /* pref_service= */ nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID) @@ -730,7 +734,8 @@ false, expected_types, std::string(), true, /* pref_service= */ nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID) @@ -787,7 +792,8 @@ /*pref_service=*/nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID) @@ -843,7 +849,8 @@ /*pref_service=*/nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID) @@ -898,7 +905,8 @@ /*pref_service=*/nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID) @@ -952,7 +960,8 @@ /*pref_service=*/nullptr, /*observer=*/IsNull())); #else - EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) + EXPECT_CALL(mock_autofill_crowdsourcing_manager_, + StartUploadRequest(_, _, _, _, _, _, _)) .Times(0); #endif // !BUILDFLAG(IS_ANDROID)
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index 059a2e7..c748ca41 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp
@@ -1190,6 +1190,18 @@ <message name="IDS_POLICY_DLP_FILES_OPEN_TIMEOUT_MESSAGE" desc="The message for notification shown after a DLP files warning times out."> Try opening your files again </message> + <message name="IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_DATA_CONTROLS_ACCESSIBLE_NAME" desc="The message is read to ChromeVox users when they focus a generic learn more link related to data controls."> + Learn more about Data Controls + </message> + <message name="IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_MALWARE_PROTECTION_ACCESSIBLE_NAME" desc="The message is read to ChromeVox users when they focus a generic learn more link related to enterprise connector's malware protection."> + Learn more about Malware protection + </message> + <message name="IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_SENSITIVE_DATA_PROTECTION_ACCESSIBLE_NAME" desc="The message is read to ChromeVox users when they focus a generic learn more link related to enterprise connector's sensitive data protection."> + Learn more about Sensitive Data protection + </message> + <message name="IDS_POLICY_DLP_FILES_JUSTIFICATION_TEXTAREA_ACCESSIBLE_DESCRIPTION" desc="The message is read to ChromeVox users when they focus the justification text area."> + Please enter a justification message having at most <ph name="MAX_CHAR_COUNT">$2<ex>280</ex></ph> characters. Used <ph name="ACTUAL_CHAR_COUNT">$1<ex>10</ex></ph> out of <ph name="MAX_CHAR_COUNT">$2<ex>280</ex></ph> characters. + </message> <message name="IDS_POLICY_DEVICE_SCHEDULED_REBOOT_TITLE" desc="The title for notification informing the user that the device will restart soon."> Device will restart very soon </message>
diff --git a/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_JUSTIFICATION_TEXTAREA_ACCESSIBLE_DESCRIPTION.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_JUSTIFICATION_TEXTAREA_ACCESSIBLE_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..e5195184 --- /dev/null +++ b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_JUSTIFICATION_TEXTAREA_ACCESSIBLE_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +149e88561be52a32afa5e3fb8221a587f2c87c99 \ No newline at end of file
diff --git a/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_DATA_CONTROLS_ACCESSIBLE_NAME.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_DATA_CONTROLS_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..790d157 --- /dev/null +++ b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_DATA_CONTROLS_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +5b06ef8eb6d89d7ad55bd2788c063e89e9ad6ece \ No newline at end of file
diff --git a/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_MALWARE_PROTECTION_ACCESSIBLE_NAME.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_MALWARE_PROTECTION_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..790d157 --- /dev/null +++ b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_MALWARE_PROTECTION_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +5b06ef8eb6d89d7ad55bd2788c063e89e9ad6ece \ No newline at end of file
diff --git a/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_SENSITIVE_DATA_PROTECTION_ACCESSIBLE_NAME.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_SENSITIVE_DATA_PROTECTION_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..790d157 --- /dev/null +++ b/components/policy_strings_grdp/IDS_POLICY_DLP_FILES_LEARN_MORE_ABOUT_SENSITIVE_DATA_PROTECTION_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +5b06ef8eb6d89d7ad55bd2788c063e89e9ad6ece \ No newline at end of file
diff --git a/content/child/browser_exposed_child_interfaces.cc b/content/child/browser_exposed_child_interfaces.cc index 3720297..19bbb5b 100644 --- a/content/child/browser_exposed_child_interfaces.cc +++ b/content/child/browser_exposed_child_interfaces.cc
@@ -26,11 +26,15 @@ base::BindRepeating(&tracing::TracedProcess::OnTracedProcessRequest), base::SequencedTaskRunner::GetCurrentDefault()); + // TODO(crbug.com/1505638): Investiagte the reason why the mojo connection + // is often created and closed for the same render process on lacros-chrome. +#if !BUILDFLAG(IS_CHROMEOS_LACROS) if (!in_browser_process) { binders->Add<mojom::SyntheticTrialConfiguration>( base::BindRepeating(&ChildProcessSyntheticTrialSyncer::Create), base::SequencedTaskRunner::GetCurrentDefault()); } +#endif // !BUILDFLAG(IS_CHROMEOS_LACROS) GetContentClient()->ExposeInterfacesToBrowser(io_task_runner, binders); }
diff --git a/content/common/service_worker/service_worker_router_evaluator.cc b/content/common/service_worker/service_worker_router_evaluator.cc index f4721ae..3da8247 100644 --- a/content/common/service_worker/service_worker_router_evaluator.cc +++ b/content/common/service_worker/service_worker_router_evaluator.cc
@@ -362,10 +362,13 @@ need_running_status_ = true; } if (url_pattern) { + RE2::Options options; + options.set_case_sensitive(!url_pattern->options.ignore_case); + #define SET_PATTERN(type_name, type) \ do { \ auto regex = ConvertToRegex(*url_pattern, type); \ - type_name##_pattern_ = std::make_unique<RE2>(regex, RE2::Options()); \ + type_name##_pattern_ = std::make_unique<RE2>(regex, options); \ if (!type_name##_pattern_->ok()) { \ RecordSetupError(ServiceWorkerRouterEvaluatorErrorEnums::kParseError); \ return false; \
diff --git a/content/common/service_worker/service_worker_router_evaluator_unittest.cc b/content/common/service_worker/service_worker_router_evaluator_unittest.cc index 6de3aba0..b14f23eb 100644 --- a/content/common/service_worker/service_worker_router_evaluator_unittest.cc +++ b/content/common/service_worker/service_worker_router_evaluator_unittest.cc
@@ -767,6 +767,80 @@ EXPECT_FALSE(eval_result.has_value()); } +TEST(ServiceWorkerRouterEvaluator, SimpleIgnoreCaseMatch) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::SafeUrlPattern url_pattern = DefaultURLPattern(); + auto parse_result = liburlpattern::Parse( + "/test/*.html", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + url_pattern.options.ignore_case = true; + rule.condition = + blink::ServiceWorkerRouterCondition::WithUrlPattern(url_pattern); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::Type::kNetwork; + source.network_source.emplace(); + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/TeSt/page.HTML"); + const auto eval_result = evaluator.EvaluateWithoutRunningStatus(request); + EXPECT_TRUE(eval_result.has_value()); + EXPECT_EQ(1U, eval_result->sources.size()); +} + +TEST(ServiceWorkerRouterEvaluator, SimpleRespectCaseAndMismatch) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::SafeUrlPattern url_pattern = DefaultURLPattern(); + auto parse_result = liburlpattern::Parse( + "/test/*.html", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + // Respects case. + url_pattern.options.ignore_case = false; + rule.condition = + blink::ServiceWorkerRouterCondition::WithUrlPattern(url_pattern); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::Type::kNetwork; + source.network_source.emplace(); + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/TeSt/page.HTML"); + const auto eval_result = evaluator.EvaluateWithoutRunningStatus(request); + EXPECT_FALSE(eval_result.has_value()); +} + TEST(ServiceWorkerRouterEvaluator, EmptyCondition) { blink::ServiceWorkerRouterRules rules; {
diff --git a/device/vr/android/xr_image_transport_base.cc b/device/vr/android/xr_image_transport_base.cc index 10bb30b9..55a61eb8 100644 --- a/device/vr/android/xr_image_transport_base.cc +++ b/device/vr/android/xr_image_transport_base.cc
@@ -194,9 +194,9 @@ static constexpr gfx::BufferFormat format = gfx::BufferFormat::RGBA_8888; static constexpr gfx::BufferUsage usage = gfx::BufferUsage::SCANOUT; - uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_SCANOUT | - gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | - gpu::SHARED_IMAGE_USAGE_GLES2; + uint32_t shared_image_usage = + gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_GLES2_WRITE; // Create a new AHardwareBuffer backed handle. buffer->scoped_ahb_handle =
diff --git a/device/vr/openxr/android/openxr_graphics_binding_open_gles.cc b/device/vr/openxr/android/openxr_graphics_binding_open_gles.cc index 10599cd3..0d123dc3 100644 --- a/device/vr/openxr/android/openxr_graphics_binding_open_gles.cc +++ b/device/vr/openxr/android/openxr_graphics_binding_open_gles.cc
@@ -220,9 +220,9 @@ static constexpr gfx::BufferFormat format = gfx::BufferFormat::RGBA_8888; static constexpr gfx::BufferUsage usage = gfx::BufferUsage::SCANOUT; - uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_SCANOUT | - gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | - gpu::SHARED_IMAGE_USAGE_GLES2; + uint32_t shared_image_usage = + gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_GLES2_WRITE; glGenTextures(1, &swap_chain_info.shared_buffer_texture);
diff --git a/device/vr/openxr/windows/openxr_graphics_binding_d3d11.cc b/device/vr/openxr/windows/openxr_graphics_binding_d3d11.cc index 86b8757..e797b9b 100644 --- a/device/vr/openxr/windows/openxr_graphics_binding_d3d11.cc +++ b/device/vr/openxr/windows/openxr_graphics_binding_d3d11.cc
@@ -183,7 +183,8 @@ gfx::Size(texture2d_desc.Width, texture2d_desc.Height); const uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | - gpu::SHARED_IMAGE_USAGE_GLES2; + gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE; gpu::MailboxHolder& mailbox_holder = swap_chain_info.mailbox_holder; auto client_shared_image = sii->CreateSharedImage(
diff --git a/docs/website b/docs/website index 8fa01e6..7e14119 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit 8fa01e615655f80075f9149063032d3e3d5956df +Subproject commit 7e14119375ad198e276c3a2eecafb4f9b0970d1f
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc index 6b11615..224e2ac 100644 --- a/extensions/browser/app_window/app_window.cc +++ b/extensions/browser/app_window/app_window.cc
@@ -587,6 +587,10 @@ void AppWindow::UpdateDraggableRegions( const std::vector<mojom::DraggableRegionPtr>& regions) { native_app_window_->UpdateDraggableRegions(regions); + + if (on_update_draggable_regions_callback_for_testing_) { + std::move(on_update_draggable_regions_callback_for_testing_).Run(); + } } void AppWindow::UpdateAppIcon(const gfx::Image& image) {
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h index 9acbf152..a9ac5a5 100644 --- a/extensions/browser/app_window/app_window.h +++ b/extensions/browser/app_window/app_window.h
@@ -394,6 +394,10 @@ native_app_window_ = std::move(native_app_window); } + void SetOnUpdateDraggableRegionsForTesting(base::OnceClosure callback) { + on_update_draggable_regions_callback_for_testing_ = std::move(callback); + } + bool DidFinishFirstNavigation() { return did_finish_first_navigation_; } protected: @@ -593,6 +597,9 @@ // processes. bool did_finish_first_navigation_ = false; + // Allows tests to wait for draggable regions to be sent from the renderer. + base::OnceClosure on_update_draggable_regions_callback_for_testing_; + base::WeakPtrFactory<AppWindow> image_loader_ptr_factory_{this}; };
diff --git a/extensions/browser/app_window/app_window_browsertest.cc b/extensions/browser/app_window/app_window_browsertest.cc index 6542e4b..7569520 100644 --- a/extensions/browser/app_window/app_window_browsertest.cc +++ b/extensions/browser/app_window/app_window_browsertest.cc
@@ -88,6 +88,28 @@ CloseAppWindow(app_window); } +IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, DraggableFramelessWindow) { + AppWindow* app_window = CreateTestAppWindow(R"({ "frame": "none" })"); + + base::RunLoop run_loop; + app_window->SetOnUpdateDraggableRegionsForTesting(run_loop.QuitClosure()); + + static constexpr char kTestScript[] = + "window.document.body.style.height = '50px';" + "window.document.body.style.width = '100px';" + "window.document.body.style.appRegion = 'drag';"; + content::WebContents* app_contents = + app_window->app_window_contents_for_test()->GetWebContents(); + EXPECT_TRUE(ExecJs(app_contents->GetPrimaryMainFrame(), kTestScript)); + + run_loop.Run(); + + NativeAppWindow* native_window = GetNativeAppWindowForAppWindow(app_window); + SkRegion* draggable_region = native_window->GetDraggableRegion(); + ASSERT_TRUE(draggable_region); + EXPECT_FALSE(draggable_region->isEmpty()); +} + #if BUILDFLAG(IS_CHROMEOS_ASH) // Disabled due to flake. https://crbug.com/1416579
diff --git a/extensions/common/mojom/app_window.mojom b/extensions/common/mojom/app_window.mojom index cba4cf6..ec1d1c9 100644 --- a/extensions/common/mojom/app_window.mojom +++ b/extensions/common/mojom/app_window.mojom
@@ -6,4 +6,8 @@ interface AppWindow { SetVisuallyDeemphasized(bool deemphasized); + + // Indicates that the frame should collect draggable regions set using the + // app-region CSS property. + SetSupportsAppRegion(bool supports_app_region); };
diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc index e4365ba9..00087f2c 100644 --- a/extensions/components/native_app_window/native_app_window_views.cc +++ b/extensions/components/native_app_window/native_app_window_views.cc
@@ -11,6 +11,8 @@ #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/app_window/app_window.h" +#include "extensions/common/mojom/app_window.mojom.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/views/controls/webview/webview.h" @@ -270,6 +272,13 @@ // initialize it with black background color. render_frame_host->GetView()->SetBackgroundColor(SK_ColorBLACK); } + + if (frameless_) { + mojo::Remote<extensions::mojom::AppWindow> app_window; + render_frame_host->GetRemoteInterfaces()->GetInterface( + app_window.BindNewPipeAndPassReceiver()); + app_window->SetSupportsAppRegion(true); + } } // views::View implementation.
diff --git a/extensions/renderer/extensions_render_frame_observer.cc b/extensions/renderer/extensions_render_frame_observer.cc index 5e11d6c..882251b 100644 --- a/extensions/renderer/extensions_render_frame_observer.cc +++ b/extensions/renderer/extensions_render_frame_observer.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/public/common/logging/logging_utils.h" #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_view.h" namespace extensions { @@ -97,6 +98,11 @@ receivers_.Add(this, std::move(receiver)); } +void ExtensionsRenderFrameObserver::SetSupportsAppRegion( + bool supports_app_region) { + render_frame()->GetWebView()->SetSupportsAppRegion(supports_app_region); +} + void ExtensionsRenderFrameObserver::SetVisuallyDeemphasized(bool deemphasized) { // TODO(danakj): This mojo API should be a MainFrame-only interface and object // rather than an every-frame interface and object.
diff --git a/extensions/renderer/extensions_render_frame_observer.h b/extensions/renderer/extensions_render_frame_observer.h index a991d579..89da5b7 100644 --- a/extensions/renderer/extensions_render_frame_observer.h +++ b/extensions/renderer/extensions_render_frame_observer.h
@@ -33,6 +33,7 @@ // Toggles visual muting of the render view area. This is on when a // constrained window is showing. void SetVisuallyDeemphasized(bool deemphasized) override; + void SetSupportsAppRegion(bool supports_app_region) override; // RenderFrameObserver implementation. void DetailedConsoleMessageAdded(
diff --git a/infra/config/generated/luci/project.cfg b/infra/config/generated/luci/project.cfg index 2ab85c9c..c90eabc 100644 --- a/infra/config/generated/luci/project.cfg +++ b/infra/config/generated/luci/project.cfg
@@ -7,7 +7,7 @@ name: "chromium" access: "group:all" lucicfg { - version: "1.42.1" + version: "1.43.1" package_dir: "../.." config_dir: "generated/luci" entry_point: "main.star"
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index 0eb43b4..0a96cd90 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -337,16 +337,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 122.0.6181.0', + 'description': 'Run with ash-chrome version 122.0.6182.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v122.0.6181.0', - 'revision': 'version:122.0.6181.0', + 'location': 'lacros_version_skew_tests_v122.0.6182.0', + 'revision': 'version:122.0.6182.0', }, ], },
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index 1364644..3af9ecdf 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "identifier": "Lacros version skew testing ash canary", "swarming": { "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ] }
diff --git a/ios/chrome/browser/find_in_page/model/find_in_page_egtest.mm b/ios/chrome/browser/find_in_page/model/find_in_page_egtest.mm index 79e0ba7..650efd5b 100644 --- a/ios/chrome/browser/find_in_page/model/find_in_page_egtest.mm +++ b/ios/chrome/browser/find_in_page/model/find_in_page_egtest.mm
@@ -265,7 +265,8 @@ // Tests that there is no query persistence when coming back to a normal tab // after switching temporarily to another tab. -- (void)testFindInPageSwitchingTabs { +// TODO(crbug.com/1500182): Re-enable this test. +- (void)FLAKY_testFindInPageSwitchingTabs { // TODO(crbug.com/1464379): Failing on iOS17 iPhone. if (@available(iOS 17.0, *)) { if (![ChromeEarlGrey isIPadIdiom]) {
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm index a826c8f..483b4fd 100644 --- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm +++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
@@ -328,10 +328,7 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kLocalOrSyncable]; - // Confirmation choice is ignored when `kReplaceSyncPromosWithSignInPromos` is - // enabled. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceKeepData]; + [SigninEarlGreyUI signOut]; // Sign in with fake supervised identity. [SigninEarlGreyUI signinWithFakeIdentity:fakeSupervisedIdentity]; @@ -367,9 +364,8 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kLocalOrSyncable]; - // Sign out from the supervised account with option to keep local data. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceKeepData]; + // Sign out from the supervised account. + [SigninEarlGreyUI signOut]; // Verify bookmarks are available. [BookmarkEarlGreyUI openBookmarks]; @@ -393,9 +389,8 @@ setupStandardBookmarksInStorage:bookmarks::StorageType::kAccount]; [ChromeEarlGreyUI waitForAppToIdle]; - // Sign out from the supervised account with option to clear local data. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + // Sign out from the supervised account. + [SigninEarlGreyUI signOut]; // Verify bookmarks are cleared. [BookmarkEarlGreyUI openBookmarks]; @@ -423,9 +418,7 @@ FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity]; - // Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceKeepData]; + [SigninEarlGreyUI signOut]; } // Tests that signing out of a managed account from the Settings works @@ -437,9 +430,7 @@ ExpectSigninConsentHistogram(signin_metrics::SigninAccountType::kManaged); ExpectNoSyncConsentHistogram(signin_metrics::SigninAccountType::kManaged); - // Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + [SigninEarlGreyUI signOut]; } // Opens the sign in screen and then cancel it by opening a new tab. Ensures
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h index 237af5d..c91c2db 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h
@@ -31,6 +31,11 @@ enableSync:(BOOL)enableSync; // Signs the primary account out of Chrome through the accounts list screen. +// Taps the "Sign Out" button and dismisses the confirmation snackbar. Assumes +// that sync sync is replaced by sign-in. ++ (void)signOut; + +// Signs the primary account out of Chrome through the accounts list screen. // Taps the "Sign Out" button, and then validated the confirmation dialog // according to `confirmation`. + (void)signOutWithConfirmationChoice:(SignOutConfirmationChoice)confirmation;
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm index e873c43..2912e17 100644 --- a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm +++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm
@@ -172,6 +172,43 @@ syncTimeout:base::Seconds(10)]; } ++ (void)signOut { + CHECK([ChromeEarlGrey isReplaceSyncWithSigninEnabled]); + [ChromeEarlGreyUI openSettingsMenu]; + [ChromeEarlGreyUI tapSettingsMenuButton:SettingsAccountButton()]; + // With ReplaceSyncWithSignin, we're now in the "manage sync" view, and + // the signout button is at the very bottom. Scroll there. + id<GREYMatcher> scrollViewMatcher = + grey_accessibilityID(kManageSyncTableViewAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:scrollViewMatcher] + performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; + + // Tap the "Sign out" button. + [[EarlGrey selectElementWithMatcher: + grey_text(l10n_util::GetNSString( + IDS_IOS_GOOGLE_ACCOUNT_SETTINGS_SIGN_OUT_ITEM))] + performAction:grey_tap()]; + // Note that there's no confirmation of signout, so the `confirmation` + // param is ignored. However, there is a snackbar - close it, so that it + // can't obstruct other UI items. + NSString* snackbarLabel = l10n_util::GetNSString( + IDS_IOS_GOOGLE_ACCOUNT_SETTINGS_SIGN_OUT_SNACKBAR_MESSAGE); + // The tap checks the existence of the snackbar and also closes it. + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(snackbarLabel)] + performAction:grey_tap()]; + + // Wait until the user is signed out. Use a longer timeout for cases where + // sign out also triggers a clear browsing data. + [ChromeEarlGrey + waitForUIElementToAppearWithMatcher:SettingsDoneButton() + timeout:base::test::ios:: + kWaitForClearBrowsingDataTimeout]; + + [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] + performAction:grey_tap()]; + [SigninEarlGrey verifySignedOut]; +} + + (void)signOutWithConfirmationChoice:(SignOutConfirmationChoice)confirmation { [ChromeEarlGreyUI openSettingsMenu]; [ChromeEarlGreyUI tapSettingsMenuButton:SettingsAccountButton()];
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm index bfbec5d..cbd2a59 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -1286,9 +1286,7 @@ [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()] assertWithMatcher:grey_sufficientlyVisible()]; - // Sign out - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + [SigninEarlGreyUI signOut]; [[EarlGrey selectElementWithMatcher:chrome_test_util::NTPLogo()] assertWithMatcher:grey_sufficientlyVisible()]; @@ -1551,8 +1549,7 @@ // Opens settings menu and ensures that Discover setting is not present. [self checkDiscoverSettingsToggleVisible:NO]; - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + [SigninEarlGreyUI signOut]; // The feed label should be visible on sign-out. [self checkFeedLabelForFeedVisible:YES];
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm index 9299956..e159c0d7 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm
@@ -288,9 +288,7 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kLocalOrSyncable]; - // Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceKeepData]; + [SigninEarlGreyUI signOut]; // Open the Bookmarks screen on the Tools menu. [BookmarkEarlGreyUI openBookmarks]; @@ -315,11 +313,7 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kAccount]; - // TODO(crbug.com/1509737) The parameter is ignored when - // kReplaceSyncPromosWithSignInPromos is enabled. Change the method to one - // that is more meaningful with Sign-in only Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + [SigninEarlGreyUI signOut]; // Open the Bookmarks screen on the Tools menu. [BookmarkEarlGreyUI openBookmarks]; @@ -342,11 +336,7 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kAccount]; - // TODO(crbug.com/1509737) The parameter is ignored when - // kReplaceSyncPromosWithSignInPromos is enabled. Change the method to one - // that is more meaningful with Sign-in only Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + [SigninEarlGreyUI signOut]; // Open the Bookmarks screen on the Tools menu. [BookmarkEarlGreyUI openBookmarks]; @@ -366,8 +356,7 @@ [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity1]; [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity1]; - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceClearData]; + [SigninEarlGreyUI signOut]; [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity2]; [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity2]; @@ -554,9 +543,7 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kLocalOrSyncable]; - // Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceNotSyncing]; + [SigninEarlGreyUI signOut]; // Open the Bookmarks screen on the Tools menu. [BookmarkEarlGreyUI openBookmarks]; @@ -575,9 +562,7 @@ [BookmarkEarlGrey setupStandardBookmarksInStorage:bookmarks::StorageType::kLocalOrSyncable]; - // Sign out. - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceNotSyncing]; + [SigninEarlGreyUI signOut]; // Open the Bookmarks screen on the Tools menu. [BookmarkEarlGreyUI openBookmarks];
diff --git a/ios/chrome/browser/ui/settings/signin_settings_egtest.mm b/ios/chrome/browser/ui/settings/signin_settings_egtest.mm index a6fd90d..710104eb 100644 --- a/ios/chrome/browser/ui/settings/signin_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/signin_settings_egtest.mm
@@ -157,8 +157,7 @@ // Close settings. [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()] performAction:grey_tap()]; - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceNotSyncing]; + [SigninEarlGreyUI signOut]; [ChromeEarlGreyUI openSettingsMenu]; // Tap on sign-in cell. [[EarlGrey selectElementWithMatcher:SettingsSignInRowMatcher()] @@ -218,8 +217,7 @@ // Close settings. [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()] performAction:grey_tap()]; - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceNotSyncing]; + [SigninEarlGreyUI signOut]; [ChromeEarlGreyUI openSettingsMenu]; // Tap on sign-in cell. [[EarlGrey selectElementWithMatcher:SettingsSignInRowMatcher()] @@ -583,8 +581,7 @@ // Sign-out then forget fakeIdentity1. [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()] performAction:grey_tap()]; - [SigninEarlGreyUI - signOutWithConfirmationChoice:SignOutConfirmationChoiceKeepData]; + [SigninEarlGreyUI signOut]; [SigninEarlGrey forgetFakeIdentity:fakeIdentity1]; // Tap on sign-in cell in settings for fakeIdentity2.
diff --git a/ios_internal b/ios_internal index c8b8487..b8fd6d1 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit c8b84877296746df0c2ad8088c1e53d19b10c8bc +Subproject commit b8fd6d1953501218760e0f7e2f0485c44d4925c1
diff --git a/media/base/video_frame_layout.cc b/media/base/video_frame_layout.cc index 53f1a26c..7e5dfe6 100644 --- a/media/base/video_frame_layout.cc +++ b/media/base/video_frame_layout.cc
@@ -156,7 +156,10 @@ planes_(std::move(planes)), is_multi_planar_(is_multi_planar), buffer_addr_align_(buffer_addr_align), - modifier_(modifier) {} + modifier_(modifier) { + // Trigger NOTREACHED() if `format` is not valid. + NumPlanes(format); +} VideoFrameLayout::~VideoFrameLayout() = default; VideoFrameLayout::VideoFrameLayout(const VideoFrameLayout&) = default;
diff --git a/media/capture/video/chromeos/camera_app_device_impl.cc b/media/capture/video/chromeos/camera_app_device_impl.cc index ee08045..044c9749 100644 --- a/media/capture/video/chromeos/camera_app_device_impl.cc +++ b/media/capture/video/chromeos/camera_app_device_impl.cc
@@ -485,4 +485,33 @@ return callbacks; } +void CameraAppDeviceImpl::SetCropRegion(const gfx::Rect& crop_region, + SetCropRegionCallback callback) { + CHECK(mojo_task_runner_->BelongsToCurrentThread()); + + base::AutoLock lock(crop_region_lock_); + crop_region_ = { + crop_region.x(), + crop_region.y(), + crop_region.width(), + crop_region.height(), + }; + + std::move(callback).Run(); +} + +void CameraAppDeviceImpl::ResetCropRegion(ResetCropRegionCallback callback) { + CHECK(mojo_task_runner_->BelongsToCurrentThread()); + + base::AutoLock lock(crop_region_lock_); + crop_region_.reset(); + + std::move(callback).Run(); +} + +std::optional<std::vector<int32_t>> CameraAppDeviceImpl::GetCropRegion() { + base::AutoLock lock(crop_region_lock_); + return crop_region_; +} + } // namespace media
diff --git a/media/capture/video/chromeos/camera_app_device_impl.h b/media/capture/video/chromeos/camera_app_device_impl.h index c2d1263..bf98134bd 100644 --- a/media/capture/video/chromeos/camera_app_device_impl.h +++ b/media/capture/video/chromeos/camera_app_device_impl.h
@@ -143,6 +143,10 @@ mojo::PendingRemote<cros::mojom::CameraInfoObserver> observer, RegisterCameraInfoObserverCallback callback) override; absl::optional<PortraitModeCallbacks> ConsumePortraitModeCallbacks(); + void SetCropRegion(const gfx::Rect& crop_region, + SetCropRegionCallback callback) override; + void ResetCropRegion(ResetCropRegionCallback callback) override; + std::optional<std::vector<int32_t>> GetCropRegion(); private: void OnMojoConnectionError(); @@ -226,6 +230,10 @@ base::Lock multi_stream_lock_; bool multi_stream_enabled_ GUARDED_BY(multi_stream_lock_) = false; + base::Lock crop_region_lock_; + std::optional<std::vector<int32_t>> crop_region_ + GUARDED_BY(crop_region_lock_); + // The weak pointers should be dereferenced and invalidated on camera device // ipc thread. base::WeakPtrFactory<CameraAppDeviceImpl> weak_ptr_factory_{this};
diff --git a/media/capture/video/chromeos/mojom/camera_app.mojom b/media/capture/video/chromeos/mojom/camera_app.mojom index 897aaf9..eb7c296 100644 --- a/media/capture/video/chromeos/mojom/camera_app.mojom +++ b/media/capture/video/chromeos/mojom/camera_app.mojom
@@ -144,6 +144,15 @@ // Registers the observer to monitor the camera info update. RegisterCameraInfoObserver( pending_remote<CameraInfoObserver> observer) => (); + + // Sets the crop region to CameraAppDevice. The value will be consumed by + // RequestManager to set it to the capture request repeatedly on every frame, + // until the new crop region value is set, or reset to the full crop region. + SetCropRegion(gfx.mojom.Rect crop_region) => (); + + // Resets the crop region set by |SetCropRegion|. It is no-ops if there is no + // crop region value set. + ResetCropRegion() => (); }; // Interface for camera device to send camera metadata to Chrome Camera App.
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc index d5d901e7..d22a03d4 100644 --- a/media/capture/video/chromeos/request_manager.cc +++ b/media/capture/video/chromeos/request_manager.cc
@@ -410,6 +410,20 @@ return; } + // Sets crop region if there is a value set from Camera app. + auto camera_app_device = + CameraAppDeviceBridgeImpl::GetInstance()->GetWeakCameraAppDevice( + device_id_); + if (camera_app_device) { + auto crop_region = camera_app_device->GetCropRegion(); + if (crop_region.has_value()) { + SetCaptureMetadata( + cros::mojom::CameraMetadataTag::ANDROID_SCALER_CROP_REGION, + cros::mojom::EntryType::TYPE_INT32, crop_region->size(), + SerializeMetadataValueFromSpan<int32_t>(*crop_region)); + } + } + auto capture_request = request_builder_->BuildRequest(std::move(stream_types), std::move(settings)); CHECK_GT(capture_request->output_buffers.size(), 0u);
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn index c7245041..ed963cb 100644 --- a/media/filters/BUILD.gn +++ b/media/filters/BUILD.gn
@@ -248,6 +248,8 @@ "hls_codec_detector.h", "hls_data_source_provider.cc", "hls_data_source_provider.h", + "hls_data_source_provider_impl.cc", + "hls_data_source_provider_impl.h", "hls_demuxer_status.h", "hls_manifest_demuxer_engine.cc", "hls_manifest_demuxer_engine.h", @@ -412,6 +414,7 @@ if (enable_hls_demuxer) { sources += [ "hls_codec_detector_unittest.cc", + "hls_data_source_provider_impl_unittest.cc", "hls_data_source_provider_unittest.cc", "hls_manifest_demuxer_engine_unittest.cc", "hls_rendition_impl_unittest.cc",
diff --git a/third_party/blink/renderer/platform/media/hls_data_source_provider_impl.cc b/media/filters/hls_data_source_provider_impl.cc similarity index 65% rename from third_party/blink/renderer/platform/media/hls_data_source_provider_impl.cc rename to media/filters/hls_data_source_provider_impl.cc index 7ce6b1c0..7976be7 100644 --- a/third_party/blink/renderer/platform/media/hls_data_source_provider_impl.cc +++ b/media/filters/hls_data_source_provider_impl.cc
@@ -2,17 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/media/hls_data_source_provider_impl.h" +#include "media/filters/hls_data_source_provider_impl.h" #include "base/logging.h" #include "base/ranges/algorithm.h" #include "base/task/bind_post_task.h" #include "base/types/pass_key.h" #include "media/formats/hls/types.h" -#include "third_party/blink/renderer/platform/media/buffered_data_source_host_impl.h" -#include "third_party/blink/renderer/platform/media/multi_buffer_data_source.h" +#include "media/base/cross_origin_data_source.h" -namespace blink { +namespace media { namespace { @@ -21,20 +20,20 @@ constexpr size_t kDefaultReadSize = 1024 * 16; void OnMultiBufferReadComplete( - std::unique_ptr<media::HlsDataSourceStream> stream, + std::unique_ptr<HlsDataSourceStream> stream, HlsDataSourceProviderImpl::ReadCb callback, int requested_read_size, int read_size) { switch (read_size) { - case media::DataSource::kReadError: { + case DataSource::kReadError: { stream->UnlockStreamPostWrite(0, true); return std::move(callback).Run( - media::HlsDataSourceProvider::ReadStatus::Codes::kError); + HlsDataSourceProvider::ReadStatus::Codes::kError); } - case media::DataSource::kAborted: { + case DataSource::kAborted: { stream->UnlockStreamPostWrite(0, true); return std::move(callback).Run( - media::HlsDataSourceProvider::ReadStatus::Codes::kAborted); + HlsDataSourceProvider::ReadStatus::Codes::kAborted); } default: { CHECK_GE(read_size, 0); @@ -47,50 +46,8 @@ } // namespace -MultiBufferDataSourceFactory::~MultiBufferDataSourceFactory() = default; HlsDataSourceProviderImpl::DataSourceFactory::~DataSourceFactory() = default; -MultiBufferDataSourceFactory::MultiBufferDataSourceFactory( - media::MediaLog* media_log, - UrlDataCb get_url_data, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - const base::TickClock* tick_clock) - : media_log_(media_log->Clone()), - get_url_data_(get_url_data), - main_task_runner_(std::move(main_task_runner)) { - buffered_data_source_host_ = std::make_unique<BufferedDataSourceHostImpl>( - base::DoNothing(), tick_clock); -} - -void MultiBufferDataSourceFactory::CreateDataSource(GURL uri, DataSourceCb cb) { - DCHECK(main_task_runner_->BelongsToCurrentThread()); - auto download_cb = -#if DCHECK_IS_ON() - base::BindRepeating( - [](const std::string url, bool is_downloading) { - DVLOG(1) << __func__ << "(" << url << ", " << is_downloading << ")"; - }, - uri.spec()); -#else - base::DoNothing(); -#endif - - get_url_data_.Run(std::move(uri), - base::BindOnce(&MultiBufferDataSourceFactory::OnUrlData, - weak_factory_.GetWeakPtr(), std::move(cb), - std::move(download_cb))); -} - -void MultiBufferDataSourceFactory::OnUrlData( - DataSourceCb cb, - base::RepeatingCallback<void(bool)> download_cb, - scoped_refptr<UrlData> data) { - DCHECK(main_task_runner_->BelongsToCurrentThread()); - std::move(cb).Run(std::make_unique<MultiBufferDataSource>( - main_task_runner_, std::move(data), media_log_.get(), - buffered_data_source_host_.get(), std::move(download_cb))); -} - HlsDataSourceProviderImpl::HlsDataSourceProviderImpl( std::unique_ptr<DataSourceFactory> factory) : data_source_factory_(std::move(factory)) {} @@ -108,9 +65,9 @@ } void HlsDataSourceProviderImpl::OnDataSourceReady( - absl::optional<media::hls::types::ByteRange> range, + absl::optional<hls::types::ByteRange> range, ReadCb callback, - std::unique_ptr<media::DataSource> data_source) { + std::unique_ptr<DataSource> data_source) { auto stream_id = stream_id_generator_.GenerateNextId(); auto it = data_source_map_.try_emplace(stream_id, std::move(data_source)); // The factory may return a CrossOriginDataSource, which must be initialized. @@ -130,7 +87,7 @@ void HlsDataSourceProviderImpl::ReadFromUrl( GURL uri, - absl::optional<media::hls::types::ByteRange> range, + absl::optional<hls::types::ByteRange> range, ReadCb callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); data_source_factory_->CreateDataSource( @@ -141,7 +98,7 @@ } void HlsDataSourceProviderImpl::ReadFromExistingStream( - std::unique_ptr<media::HlsDataSourceStream> stream, + std::unique_ptr<HlsDataSourceStream> stream, ReadCb callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(stream); @@ -149,7 +106,7 @@ auto it = data_source_map_.find(stream->stream_id()); if (it == data_source_map_.end()) { std::move(callback).Run( - media::HlsDataSourceProvider::ReadStatus::Codes::kError); + HlsDataSourceProvider::ReadStatus::Codes::kError); return; } @@ -185,8 +142,8 @@ } void HlsDataSourceProviderImpl::DataSourceInitialized( - media::HlsDataSourceStream::StreamId stream_id, - absl::optional<media::hls::types::ByteRange> range, + HlsDataSourceStream::StreamId stream_id, + absl::optional<hls::types::ByteRange> range, ReadCb callback, bool success) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -196,11 +153,11 @@ data_source_map_.erase(it); } std::move(callback).Run( - media::HlsDataSourceProvider::ReadStatus::Codes::kAborted); + HlsDataSourceProvider::ReadStatus::Codes::kAborted); return; } - auto stream = std::make_unique<media::HlsDataSourceStream>( + auto stream = std::make_unique<HlsDataSourceStream>( stream_id, base::BindPostTaskToCurrentDefault( base::BindOnce(&HlsDataSourceProviderImpl::OnStreamReleased, @@ -210,7 +167,7 @@ } void HlsDataSourceProviderImpl::OnStreamReleased( - media::HlsDataSourceStream::StreamId stream_id) { + HlsDataSourceStream::StreamId stream_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto it = data_source_map_.find(stream_id); if (it != data_source_map_.end()) {
diff --git a/media/filters/hls_data_source_provider_impl.h b/media/filters/hls_data_source_provider_impl.h new file mode 100644 index 0000000..3f79a16 --- /dev/null +++ b/media/filters/hls_data_source_provider_impl.h
@@ -0,0 +1,68 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_FILTERS_HLS_DATA_SOURCE_PROVIDER_IMPL_H_ +#define MEDIA_FILTERS_HLS_DATA_SOURCE_PROVIDER_IMPL_H_ + +#include <memory> +#include "base/memory/raw_ptr.h" +#include "base/memory/scoped_refptr.h" +#include "base/task/single_thread_task_runner.h" +#include "base/time/tick_clock.h" +#include "base/types/pass_key.h" +#include "media/base/data_source.h" +#include "media/base/media_export.h" +#include "media/base/media_log.h" +#include "media/filters/hls_data_source_provider.h" + +namespace media { + +class MEDIA_EXPORT HlsDataSourceProviderImpl : public HlsDataSourceProvider { + public: + // An instance of DataSourceFactory allows separation of DataSource creation + // and DataSourceStream buffer management for easier testing. + class DataSourceFactory { + public: + using DataSourceCb = base::OnceCallback<void(std::unique_ptr<DataSource>)>; + virtual ~DataSourceFactory() = 0; + virtual void CreateDataSource(GURL uri, DataSourceCb cb) = 0; + }; + + ~HlsDataSourceProviderImpl() override; + explicit HlsDataSourceProviderImpl( + std::unique_ptr<DataSourceFactory> factory); + + // HlsDataSourceProvider implementation + void ReadFromUrl(GURL uri, + absl::optional<hls::types::ByteRange> range, + ReadCb callback) override; + void ReadFromExistingStream(std::unique_ptr<HlsDataSourceStream> stream, + ReadCb callback) override; + void AbortPendingReads(base::OnceClosure cb) override; + + private: + void OnDataSourceReady(absl::optional<hls::types::ByteRange> range, + ReadCb callback, + std::unique_ptr<DataSource> data_source); + void OnStreamReleased(HlsDataSourceStream::StreamId stream_id); + void DataSourceInitialized(HlsDataSourceStream::StreamId stream_id, + absl::optional<hls::types::ByteRange> range, + ReadCb callback, + bool success); + + std::unique_ptr<DataSourceFactory> data_source_factory_; + + HlsDataSourceStream::StreamId::Generator stream_id_generator_; + + base::flat_map<HlsDataSourceStream::StreamId, std::unique_ptr<DataSource>> + data_source_map_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<HlsDataSourceProviderImpl> weak_factory_{this}; +}; + +} // namespace media + +#endif // #ifndef MEDIA_FILTERS_HLS_DATA_SOURCE_PROVIDER_IMPL_H_
diff --git a/third_party/blink/renderer/platform/media/hls_data_source_provider_impl_unittest.cc b/media/filters/hls_data_source_provider_impl_unittest.cc similarity index 89% rename from third_party/blink/renderer/platform/media/hls_data_source_provider_impl_unittest.cc rename to media/filters/hls_data_source_provider_impl_unittest.cc index 7878ad7..935b8292 100644 --- a/third_party/blink/renderer/platform/media/hls_data_source_provider_impl_unittest.cc +++ b/media/filters/hls_data_source_provider_impl_unittest.cc
@@ -14,11 +14,10 @@ #include "media/base/mock_media_log.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/media/buffered_data_source_host_impl.h" -#include "third_party/blink/renderer/platform/media/hls_data_source_provider_impl.h" -#include "third_party/blink/renderer/platform/media/multi_buffer_data_source.h" +#include "media/filters/hls_data_source_provider_impl.h" +#include "media/base/cross_origin_data_source.h" -namespace blink { +namespace media { using base::test::RunOnceCallback; using testing::_; @@ -37,7 +36,7 @@ namespace { -class MockDataSource : public media::CrossOriginDataSource { +class MockDataSource : public CrossOriginDataSource { public: // Mocked methods from CrossOriginDataSource MOCK_METHOD(bool, IsCorsCrossOrigin, (), (const, override)); @@ -65,7 +64,7 @@ MOCK_METHOD(int64_t, GetMemoryUsage, (), (override)); MOCK_METHOD(void, SetPreload, - (media::DataSource::Preload preload), + (DataSource::Preload preload), (override)); MOCK_METHOD(GURL, GetUrlAfterRedirects, (), (const, override)); MOCK_METHOD(void, @@ -141,7 +140,7 @@ factory_->AddReadExpectation(0, 16384, 16384); impl_->ReadFromUrl( GURL("example.com"), absl::nullopt, - base::BindOnce([](media::HlsDataSourceProvider::ReadResult result) { + base::BindOnce([](HlsDataSourceProvider::ReadResult result) { ASSERT_TRUE(result.has_value()); auto stream = std::move(result).value(); ASSERT_EQ(stream->read_position(), 16384lu); @@ -155,7 +154,7 @@ factory_->AddReadExpectation(0, 16384, 400); impl_->ReadFromUrl( GURL("example.com"), absl::nullopt, - base::BindOnce([](media::HlsDataSourceProvider::ReadResult result) { + base::BindOnce([](HlsDataSourceProvider::ReadResult result) { ASSERT_TRUE(result.has_value()); auto stream = std::move(result).value(); ASSERT_EQ(stream->read_position(), 400lu); @@ -169,8 +168,8 @@ // at an offset of 99. The read should be from 99, size of 4242. factory_->AddReadExpectation(99, 4242, 4242); impl_->ReadFromUrl( - GURL("example.com"), media::hls::types::ByteRange::Validate(4242, 99), - base::BindOnce([](media::HlsDataSourceProvider::ReadResult result) { + GURL("example.com"), hls::types::ByteRange::Validate(4242, 99), + base::BindOnce([](HlsDataSourceProvider::ReadResult result) { ASSERT_TRUE(result.has_value()); auto stream = std::move(result).value(); ASSERT_EQ(stream->read_position(), 4341lu); @@ -189,7 +188,7 @@ GURL("example.com"), absl::nullopt, base::BindOnce( [](HlsDataSourceProviderImpl* impl_ptr, - media::HlsDataSourceProvider::ReadResult result) { + HlsDataSourceProvider::ReadResult result) { ASSERT_TRUE(result.has_value()); auto stream = std::move(result).value(); ASSERT_EQ(stream->read_position(), 16384lu); @@ -200,7 +199,7 @@ std::move(stream), base::BindOnce( [](HlsDataSourceProviderImpl* impl_ptr, - media::HlsDataSourceProvider::ReadResult result) { + HlsDataSourceProvider::ReadResult result) { ASSERT_TRUE(result.has_value()); auto stream = std::move(result).value(); ASSERT_EQ(stream->read_position(), 32768lu); @@ -210,7 +209,7 @@ impl_ptr->ReadFromExistingStream( std::move(stream), base::BindOnce( - [](media::HlsDataSourceProvider::ReadResult + [](HlsDataSourceProvider::ReadResult result) { ASSERT_TRUE(result.has_value()); auto stream = std::move(result).value(); @@ -233,10 +232,10 @@ EXPECT_CALL(*mock_data_source, Abort()).Times(0); EXPECT_CALL(*mock_data_source, Stop()).Times(0); - media::DataSource::ReadCB read_cb; + DataSource::ReadCB read_cb; EXPECT_CALL(*mock_data_source, Read(0, _, _, _)) .WillOnce( - [&read_cb](int64_t, int, uint8_t*, media::DataSource::ReadCB cb) { + [&read_cb](int64_t, int, uint8_t*, DataSource::ReadCB cb) { read_cb = std::move(cb); }); @@ -245,7 +244,7 @@ impl_->ReadFromUrl(GURL("example.com"), absl::nullopt, base::BindOnce( [](bool* read_canary, - media::HlsDataSourceProvider::ReadResult result) { + HlsDataSourceProvider::ReadResult result) { *read_canary = true; }, &has_been_read)); @@ -278,7 +277,7 @@ impl_->ReadFromUrl(GURL("example.com"), absl::nullopt, base::BindOnce( [](bool* read_canary, - media::HlsDataSourceProvider::ReadResult result) { + HlsDataSourceProvider::ReadResult result) { *read_canary = true; }, &has_been_read));
diff --git a/net/dns/public/dns_over_https_server_config.cc b/net/dns/public/dns_over_https_server_config.cc index 3dcfa133..5767f1b 100644 --- a/net/dns/public/dns_over_https_server_config.cc +++ b/net/dns/public/dns_over_https_server_config.cc
@@ -30,10 +30,9 @@ std::string canonical; url::StdStringCanonOutput output(&canonical); url::Parsed canonical_parsed; - bool is_valid = - url::CanonicalizeStandardURL(url.data(), url.size(), parsed, - url::SchemeType::SCHEME_WITH_HOST_AND_PORT, - nullptr, &output, &canonical_parsed); + bool is_valid = url::CanonicalizeStandardURL( + url.data(), parsed, url::SchemeType::SCHEME_WITH_HOST_AND_PORT, nullptr, + &output, &canonical_parsed); if (!is_valid) return absl::nullopt; const url::Component& scheme_range = canonical_parsed.scheme;
diff --git a/net/quic/quic_http3_logger.cc b/net/quic/quic_http3_logger.cc index fce189ad..de1bd0c1 100644 --- a/net/quic/quic_http3_logger.cc +++ b/net/quic/quic_http3_logger.cc
@@ -147,7 +147,6 @@ frame.values.size() + 1, /* min = */ 1, /* max = */ 10, /* buckets = */ 10); int reserved_identifier_count = 0; - bool settings_extended_connect_enabled = false; for (const auto& value : frame.values) { if (value.first == quic::SETTINGS_QPACK_MAX_TABLE_CAPACITY) { UMA_HISTOGRAM_COUNTS_1M( @@ -158,8 +157,6 @@ } else if (value.first == quic::SETTINGS_QPACK_BLOCKED_STREAMS) { UMA_HISTOGRAM_COUNTS_1000( "Net.QuicSession.ReceivedSettings.BlockedStreams", value.second); - } else if (value.first == quic::SETTINGS_ENABLE_CONNECT_PROTOCOL) { - settings_extended_connect_enabled = value.second == 1; } else if (value.first >= 0x21 && value.first % 0x1f == 2) { // Reserved setting identifiers are defined at // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#name-defined-settings-parameters. @@ -174,9 +171,6 @@ "Net.QuicSession.ReceivedSettings.ReservedCountPlusOne", reserved_identifier_count + 1, /* min = */ 1, /* max = */ 5, /* buckets = */ 5); - UMA_HISTOGRAM_BOOLEAN( - "Net.QuicSession.ReceivedSettings.EnableExtendedConnect", - settings_extended_connect_enabled); if (!net_log_.IsCapturing()) return;
diff --git a/net/tools/dump_cache/dump_cache.cc b/net/tools/dump_cache/dump_cache.cc index 16ae2dc..dd21784 100644 --- a/net/tools/dump_cache/dump_cache.cc +++ b/net/tools/dump_cache/dump_cache.cc
@@ -10,6 +10,7 @@ #include "base/at_exit.h" #include "base/command_line.h" +#include "base/i18n/icu_util.h" #include "base/strings/string_util.h" #include "net/disk_cache/blockfile/disk_format.h" #include "net/tools/dump_cache/dump_files.h" @@ -71,6 +72,9 @@ // Setup an AtExitManager so Singleton objects will be destroyed. base::AtExitManager at_exit_manager; + // base::UnlocalizedTimeFormatWithPattern() depends on ICU. + base::i18n::InitializeICU(); + base::CommandLine::Init(argc, argv); const base::CommandLine& command_line = @@ -83,9 +87,9 @@ if (input_path.empty()) return Help(); - int version = GetMajorVersion(input_path); - if (version != 2) + if (!CheckFileVersion(input_path)) { return FILE_ACCESS_ERROR; + } if (command_line.HasSwitch(kDumpContents)) return DumpContents(input_path);
diff --git a/net/tools/dump_cache/dump_files.cc b/net/tools/dump_cache/dump_files.cc index bd8449e..da5951a 100644 --- a/net/tools/dump_cache/dump_files.cc +++ b/net/tools/dump_cache/dump_files.cc
@@ -53,12 +53,27 @@ return true; } -int GetMajorVersionFromFile(const base::FilePath& name) { +int GetMajorVersionFromIndexFile(const base::FilePath& name) { disk_cache::IndexHeader header; if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) return 0; + if (header.magic != disk_cache::kIndexMagic) { + return 0; + } + return header.version; +} - return header.version >> 16; +int GetMajorVersionFromBlockFile(const base::FilePath& name) { + disk_cache::BlockFileHeader header; + if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) { + return 0; + } + + if (header.magic != disk_cache::kBlockMagic) { + return 0; + } + + return header.version; } // Dumps the contents of the Stats record. @@ -394,30 +409,24 @@ // ----------------------------------------------------------------------- -int GetMajorVersion(const base::FilePath& input_path) { +bool CheckFileVersion(const base::FilePath& input_path) { base::FilePath index_name(input_path.Append(kIndexName)); - int version = GetMajorVersionFromFile(index_name); - if (!version) - return 0; + int index_version = GetMajorVersionFromIndexFile(index_name); + if (!index_version || index_version != disk_cache::kVersion3_0) { + return false; + } - base::FilePath data_name(input_path.Append(FILE_PATH_LITERAL("data_0"))); - if (version != GetMajorVersionFromFile(data_name)) - return 0; - - data_name = input_path.Append(FILE_PATH_LITERAL("data_1")); - if (version != GetMajorVersionFromFile(data_name)) - return 0; - - data_name = input_path.Append(FILE_PATH_LITERAL("data_2")); - if (version != GetMajorVersionFromFile(data_name)) - return 0; - - data_name = input_path.Append(FILE_PATH_LITERAL("data_3")); - if (version != GetMajorVersionFromFile(data_name)) - return 0; - - return version; + constexpr int kCurrentBlockVersion = disk_cache::kBlockVersion2; + for (int i = 0; i < disk_cache::kFirstAdditionalBlockFile; i++) { + std::string data_name = "data_" + base::NumberToString(i); + auto data_path = input_path.AppendASCII(data_name); + int block_version = GetMajorVersionFromBlockFile(data_path); + if (!block_version || block_version != kCurrentBlockVersion) { + return false; + } + } + return true; } // Dumps the headers of all files.
diff --git a/net/tools/dump_cache/dump_files.h b/net/tools/dump_cache/dump_files.h index 8a6c83c..6d9fded 100644 --- a/net/tools/dump_cache/dump_files.h +++ b/net/tools/dump_cache/dump_files.h
@@ -11,8 +11,8 @@ #include "base/files/file_path.h" -// Returns the major version of the specified cache. -int GetMajorVersion(const base::FilePath& input_path); +// Check file version of the specified cache. +bool CheckFileVersion(const base::FilePath& input_path); // Dumps all entries from the cache. int DumpContents(const base::FilePath& input_path);
diff --git a/services/webnn/public/mojom/webnn_graph.mojom b/services/webnn/public/mojom/webnn_graph.mojom index 271142a3..08aa92ef 100644 --- a/services/webnn/public/mojom/webnn_graph.mojom +++ b/services/webnn/public/mojom/webnn_graph.mojom
@@ -288,6 +288,29 @@ SymmetricPadding symmetric; }; +// This operator performs the following normalization, defined as: +// Output = scale * (input - mean) / sqrt(variance + epsilon) + bias, where +// mean and variance are computed per instance per channel. The specified +// layout determines how to choose the channel. +struct InstanceNormalization { + // The input operand (referenced by input_operand_id) must be distinct from + // the output operand (referenced by output_operand_id). + uint64 input_operand_id; + uint64 output_operand_id; + + // The optional 1-D tensor of the scale values whose size is equal to the + // size of the feature dimension of the input. + uint64? scale_operand_id; + // The optional 1-D tensor of the bias values whose size is equal to the + // size of the feature dimension of the input. + uint64? bias_operand_id; + // A float scalar which specifies a small value to prevent computational + // error due to divide-by-zero. + float epsilon = 1e-5; + // The layout format of the input. + InputOperandLayout layout; +}; + // Represents matmul operation which compute the matrix product of two input tensors. struct Matmul { // The id of `a` operand is used to get the `Operand` description from @@ -724,6 +747,7 @@ Gather gather; Gemm gemm; LayerNormalization layer_normalization; + InstanceNormalization instance_normalization; LeakyRelu leaky_relu; Matmul matmul; Pad pad;
diff --git a/services/webnn/webnn_graph_impl.cc b/services/webnn/webnn_graph_impl.cc index a7d8fe9..e95c86a 100644 --- a/services/webnn/webnn_graph_impl.cc +++ b/services/webnn/webnn_graph_impl.cc
@@ -328,6 +328,28 @@ return component_attributes; } +webnn::InstanceNormalizationAttributes ConvertToInstanceNormalizationAttributes( + const IdToOperandMap& id_to_operand_map, + const mojom::InstanceNormalizationPtr& instance_normalization) { + webnn::InstanceNormalizationAttributes component_attributes; + const auto& scale_operand_id = instance_normalization->scale_operand_id; + if (scale_operand_id) { + const mojom::OperandPtr& scale_operand = + id_to_operand_map.at(scale_operand_id.value()); + component_attributes.scale = ConvertToComponentOperand(scale_operand.get()); + } + const auto& bias_operand_id = instance_normalization->bias_operand_id; + if (bias_operand_id) { + const mojom::OperandPtr& bias_operand = + id_to_operand_map.at(bias_operand_id.value()); + component_attributes.bias = ConvertToComponentOperand(bias_operand.get()); + } + component_attributes.layout = + MojoInputOperandLayoutToComponent(instance_normalization->layout); + + return component_attributes; +} + webnn::SliceAttributes ConvertToSliceAttributes( const webnn::mojom::SlicePtr& slice) { webnn::SliceAttributes component_attributes; @@ -800,6 +822,46 @@ return true; } +bool ValidateInstanceNormalization( + const IdToOperandMap& id_to_operand_map, + const mojom::InstanceNormalizationPtr& instance_normalization) { + const auto* input = GetMojoOperand(id_to_operand_map, + instance_normalization->input_operand_id); + const auto* output = GetMojoOperand( + id_to_operand_map, instance_normalization->output_operand_id); + if (!input || !output || output == input) { + // The instanceNormalization operator is invalid. + return false; + } + const auto& scale_operand_id = instance_normalization->scale_operand_id; + if (scale_operand_id && + (!id_to_operand_map.contains(scale_operand_id.value()) || + scale_operand_id.value() == instance_normalization->output_operand_id)) { + // The scale operand is invalid. + return false; + } + const auto& bias_operand_id = instance_normalization->bias_operand_id; + if (bias_operand_id && + (!id_to_operand_map.contains(bias_operand_id.value()) || + bias_operand_id.value() == instance_normalization->output_operand_id)) { + // The bias operand is invalid. + return false; + } + + const auto validated_output = ValidateInstanceNormalizationAndInferOutput( + ConvertToComponentOperand(input), + ConvertToInstanceNormalizationAttributes(id_to_operand_map, + instance_normalization)); + if (!validated_output.has_value()) { + return false; + } + if (validated_output != ConvertToComponentOperand(output)) { + return false; + } + + return true; +} + bool ValidateMatmul(const IdToOperandMap& id_to_operand_map, const mojom::MatmulPtr& matmul) { auto* a = GetMojoOperand(id_to_operand_map, matmul->a_operand_id); @@ -1170,6 +1232,9 @@ case mojom::Operation::Tag::kLayerNormalization: return ValidateLayerNormalization(id_to_operand_map, operation->get_layer_normalization()); + case mojom::Operation::Tag::kInstanceNormalization: + return ValidateInstanceNormalization( + id_to_operand_map, operation->get_instance_normalization()); case mojom::Operation::Tag::kLeakyRelu: return ValidateLeakyRelu(id_to_operand_map, operation->get_leaky_relu()); case mojom::Operation::Tag::kMatmul:
diff --git a/services/webnn/webnn_graph_impl_unittest.cc b/services/webnn/webnn_graph_impl_unittest.cc index 58a30f2..94663a1 100644 --- a/services/webnn/webnn_graph_impl_unittest.cc +++ b/services/webnn/webnn_graph_impl_unittest.cc
@@ -2650,6 +2650,208 @@ } } +struct InstanceNormalizationTester { + OperandInfo input; + absl::optional<OperandInfo> scale; + absl::optional<OperandInfo> bias; + struct InstanceNormalizationAttributes { + absl::optional<uint64_t> scale_operand_id; + absl::optional<uint64_t> bias_operand_id; + mojom::InputOperandLayout layout = + mojom::InputOperandLayout::kChannelsFirst; + float epsilon = 1e-5; + }; + InstanceNormalizationAttributes attributes; + OperandInfo output; + bool expected; + + void Test() { + // Build the graph with mojo type. + GraphInfoBuilder builder; + uint64_t input_operand_id = + builder.BuildInput("input", input.dimensions, input.type); + uint64_t output_operand_id = + builder.BuildOutput("output", output.dimensions, output.type); + + if (scale) { + attributes.scale_operand_id = + builder.BuildInput("scale", scale->dimensions, scale->type); + } + if (bias) { + attributes.bias_operand_id = + builder.BuildInput("bias", bias->dimensions, bias->type); + } + builder.BuildInstanceNormalization(input_operand_id, output_operand_id, + std::move(attributes)); + EXPECT_EQ(WebNNGraphImpl::ValidateGraph(builder.GetGraphInfo()), expected); + } +}; + +TEST_F(WebNNGraphImplTest, InstanceNormalizationTest) { + { + // Test building instanceNormalization with default option. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = true} + .Test(); + } + { + // Test building instanceNormalization with layout = kChannelsLast. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .scale = OperandInfo{.type = mojom::Operand::DataType::kFloat32, + .dimensions = {3}}, + .bias = OperandInfo{.type = mojom::Operand::DataType::kFloat32, + .dimensions = {3}}, + .attributes = {.layout = mojom::InputOperandLayout::kChannelsLast}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = true} + .Test(); + } + { + // Test building instanceNormalization with default layout = kChannelsFirst. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .scale = OperandInfo{.type = mojom::Operand::DataType::kFloat32, + .dimensions = {2}}, + .bias = OperandInfo{.type = mojom::Operand::DataType::kFloat32, + .dimensions = {2}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = true} + .Test(); + } + { + // Test instanceNormalization when input data type and scale data type + // mismatched. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .scale = OperandInfo{.type = mojom::Operand::DataType::kInt32, + .dimensions = {2}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = false} + .Test(); + } + { + // Test building instanceNormalization when the size of scale is not equal + // to the size of the feature dimension of the input. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .scale = OperandInfo{.type = mojom::Operand::DataType::kFloat32, + .dimensions = {3}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = false} + .Test(); + } + { + // Test instanceNormalization when input data type and bias data type + // mismatched. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .bias = OperandInfo{.type = mojom::Operand::DataType::kInt32, + .dimensions = {2}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = false} + .Test(); + } + { + // Test building instanceNormalization when the size of bias is not equal + // to the size of the feature dimension of the input. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .bias = OperandInfo{.type = mojom::Operand::DataType::kFloat32, + .dimensions = {2}}, + .attributes = {.layout = mojom::InputOperandLayout::kChannelsLast}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .expected = false} + .Test(); + } + { + // Test the invalid graph for output type is not the same as input type. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .output = {.type = mojom::Operand::DataType::kInt32, + .dimensions = {1, 2, 3, 3}}, + .expected = false} + .Test(); + } + { + // Test the invalid graph for output shape is not the same as input shape. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3, 3}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 1, 3, 3}}, + .expected = false} + .Test(); + } + { + // Test the invalid graph for input is not a 4-D tensor. + InstanceNormalizationTester{ + .input = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3}}, + .output = {.type = mojom::Operand::DataType::kFloat32, + .dimensions = {1, 2, 3}}, + .expected = false} + .Test(); + } + { + // Test the invalid graph for input operand == output operand. + GraphInfoBuilder builder; + uint64_t input_operand_id = builder.BuildInput( + "input", {1, 2, 3, 4}, mojom::Operand::DataType::kFloat32); + builder.BuildInstanceNormalization( + input_operand_id, input_operand_id, + InstanceNormalizationTester::InstanceNormalizationAttributes{}); + EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(builder.GetGraphInfo())); + } + { + // Test the invalid graph when the output is the same as the scale. + GraphInfoBuilder builder; + uint64_t input_operand_id = builder.BuildInput( + "input", {1, 2, 3, 4}, mojom::Operand::DataType::kFloat32); + uint64_t scale_operand_id = + builder.BuildInput("scale", {2}, mojom::Operand::DataType::kFloat32); + + InstanceNormalizationTester::InstanceNormalizationAttributes attributes; + attributes.scale_operand_id = scale_operand_id; + + builder.BuildInstanceNormalization(input_operand_id, scale_operand_id, + std::move(attributes)); + EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(builder.GetGraphInfo())); + } + { + // Test the invalid graph when the output is the same as the bias. + GraphInfoBuilder builder; + uint64_t input_operand_id = builder.BuildInput( + "input", {1, 2, 3, 4}, mojom::Operand::DataType::kFloat32); + uint64_t bias_operand_id = + builder.BuildInput("bias", {2}, mojom::Operand::DataType::kFloat32); + + InstanceNormalizationTester::InstanceNormalizationAttributes attributes; + attributes.bias_operand_id = bias_operand_id; + + builder.BuildInstanceNormalization(input_operand_id, bias_operand_id, + std::move(attributes)); + EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(builder.GetGraphInfo())); + } +} + struct LayerNormalizationTester { OperandInfo input; absl::optional<OperandInfo> scale;
diff --git a/services/webnn/webnn_test_utils.h b/services/webnn/webnn_test_utils.h index c909b29..bbba056 100644 --- a/services/webnn/webnn_test_utils.h +++ b/services/webnn/webnn_test_utils.h
@@ -260,6 +260,33 @@ std::move(layer_normalization))); } + // A `InstanceNormalizationAttributes` type should have the following members: + // struct InstanceNormalizationAttributes { + // absl::optional<uint64_t> scale_operand_id; + // absl::optional<uint64_t> bias_operand_id; + // float epsilon = 1e-5; + // mojom::InputOperandLayout input_layout; + // }; + template <typename InstanceNormalizationAttributes> + void BuildInstanceNormalization( + uint64_t input_operand_id, + uint64_t output_operand_id, + const InstanceNormalizationAttributes& attributes) { + mojom::InstanceNormalizationPtr instance_normalization = + mojom::InstanceNormalization::New(); + instance_normalization->input_operand_id = input_operand_id; + instance_normalization->output_operand_id = output_operand_id; + + instance_normalization->scale_operand_id = attributes.scale_operand_id; + instance_normalization->bias_operand_id = attributes.bias_operand_id; + instance_normalization->layout = attributes.layout; + instance_normalization->epsilon = attributes.epsilon; + + graph_info_->operations.push_back( + mojom::Operation::NewInstanceNormalization( + std::move(instance_normalization))); + } + void BuildLeakyRelu(uint64_t input_operand_id, uint64_t output_operand_id, float alpha);
diff --git a/services/webnn/webnn_utils.cc b/services/webnn/webnn_utils.cc index 940be86..880ec4ba 100644 --- a/services/webnn/webnn_utils.cc +++ b/services/webnn/webnn_utils.cc
@@ -30,6 +30,8 @@ return "gather"; case mojom::Operation::Tag::kGemm: return "gemm"; + case mojom::Operation::Tag::kInstanceNormalization: + return "instanceNormalization"; case mojom::Operation::Tag::kLayerNormalization: return "layerNormalization"; case mojom::Operation::Tag::kLeakyRelu:
diff --git a/skia/ext/skia_utils_mac.h b/skia/ext/skia_utils_mac.h index fff7a46..b7adeeaa 100644 --- a/skia/ext/skia_utils_mac.h +++ b/skia/ext/skia_utils_mac.h
@@ -82,27 +82,49 @@ #ifdef __OBJC__ // Draws an NSImage with a given size into a SkBitmap. -SK_API SkBitmap NSImageToSkBitmapWithColorSpace(NSImage* image, +SK_API SkBitmap NSImageToSkBitmap(NSImage* image, bool is_opaque); + +// TODO(https://crbug.com/1495334): Remove callers to this function. +inline SkBitmap NSImageToSkBitmapWithColorSpace(NSImage* image, bool is_opaque, - CGColorSpaceRef color_space); + CGColorSpaceRef color_space) { + return NSImageToSkBitmap(image, is_opaque); +} // Draws an NSImageRep with a given size into a SkBitmap. -SK_API SkBitmap NSImageRepToSkBitmapWithColorSpace(NSImageRep* image, +SK_API SkBitmap NSImageRepToSkBitmap(NSImageRep* image, + NSSize size, + bool is_opaque); + +// TODO(https://crbug.com/1495334): Remove callers to this function. +inline SkBitmap NSImageRepToSkBitmapWithColorSpace(NSImageRep* image, NSSize size, bool is_opaque, - CGColorSpaceRef colorspace); + CGColorSpaceRef colorspace) { + return NSImageRepToSkBitmap(image, size, is_opaque); +} // Given an SkBitmap, return an autoreleased NSBitmapImageRep. -SK_API NSBitmapImageRep* SkBitmapToNSBitmapImageRepWithColorSpace( +SK_API NSBitmapImageRep* SkBitmapToNSBitmapImageRep(const SkBitmap& skiaBitmap); + +// TODO(https://crbug.com/1495334): Remove callers to this function. +inline NSBitmapImageRep* SkBitmapToNSBitmapImageRepWithColorSpace( const SkBitmap& skiaBitmap, - CGColorSpaceRef colorSpace); + CGColorSpaceRef colorSpace) { + return SkBitmapToNSBitmapImageRep(skiaBitmap); +} #endif // __OBJC__ // Given an SkBitmap and a color space, return an autoreleased NSImage. // TODO(https://crbug.com/1433041): Restrict this to Objective-C callers. -SK_API NSImage* SkBitmapToNSImageWithColorSpace(const SkBitmap& icon, - CGColorSpaceRef colorSpace); +SK_API NSImage* SkBitmapToNSImage(const SkBitmap& icon); + +// TODO(https://crbug.com/1495334): Remove callers to this function. +inline NSImage* SkBitmapToNSImageWithColorSpace(const SkBitmap& icon, + CGColorSpaceRef colorSpace) { + return SkBitmapToNSImage(icon); +} } // namespace skia
diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm index 6629a96..ab4c21a 100644 --- a/skia/ext/skia_utils_mac.mm +++ b/skia/ext/skia_utils_mac.mm
@@ -9,28 +9,64 @@ #include <memory> +#include "base/apple/foundation_util.h" #include "base/apple/scoped_cftyperef.h" #include "base/check.h" #include "base/mac/mac_util.h" #include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/utils/mac/SkCGUtils.h" namespace { // Draws an NSImage or an NSImageRep with a given size into a SkBitmap. -SkBitmap NSImageOrNSImageRepToSkBitmapWithColorSpace( - NSImage* image, - NSImageRep* image_rep, - NSSize size, - bool is_opaque, - CGColorSpaceRef color_space) { +SkBitmap NSImageOrNSImageRepToSkBitmap(NSImage* image, + NSImageRep* image_rep, + NSSize size, + bool is_opaque) { // Only image or image_rep should be provided, not both. DCHECK((image != nullptr) ^ (image_rep != nullptr)); - SkBitmap bitmap; - if (!bitmap.tryAllocN32Pixels(size.width, size.height, is_opaque)) - return bitmap; // Return |bitmap| which should respond true to isNull(). + // Determine the color space for the SkBitmap. Any color space is acceptable, + // but if we can match the color space of `image` or `image_rep` then the + // result will be higher fidelity. + sk_sp<SkColorSpace> sk_color_space; + { + NSBitmapImageRep* bitmap_image_rep = nil; + if (image_rep) { + // If `image_rep` is an NSBitmapImageRep, then use its color space. + bitmap_image_rep = base::apple::ObjCCast<NSBitmapImageRep>(image_rep); + } else { + // If `image` has an NSBitmapImageRep, then use the color space of the + // first encountered NSBitmapImageRep. + for (NSImageRep* rep in [image representations]) { + bitmap_image_rep = base::apple::ObjCCast<NSBitmapImageRep>(rep); + if (bitmap_image_rep) { + break; + } + } + } + sk_color_space = SkMakeColorSpaceFromCGColorSpace( + [[bitmap_image_rep colorSpace] CGColorSpace]); + // If we did not extract a color space that matches the input, default to + // using sRGB. + if (!sk_color_space) { + sk_color_space = SkColorSpace::MakeSRGB(); + } + } + + // Set the CGColorSpace of the CGContext to match the SkColorSpace. + base::apple::ScopedCFTypeRef<CGColorSpaceRef> cg_color_space( + SkCreateCGColorSpace(sk_color_space.get())); + + SkImageInfo info = SkImageInfo::MakeN32( + size.width, size.height, + is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType, sk_color_space); + SkBitmap bitmap; + if (!bitmap.tryAllocPixels(info)) { + return bitmap; // Return |bitmap| which should respond true to isNull(). + } void* data = bitmap.getPixels(); @@ -41,7 +77,7 @@ && SK_G32_SHIFT == (g) && SK_B32_SHIFT == (b)) #if defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0) base::apple::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate( - data, size.width, size.height, 8, size.width * 4, color_space, + data, size.width, size.height, 8, size.width * 4, cg_color_space.get(), uint32_t{kCGImageAlphaPremultipliedFirst} | kCGBitmapByteOrder32Host)); #else #error We require that Skia's and CoreGraphics's recommended \ @@ -210,26 +246,22 @@ return SkBitmap(); } -SkBitmap NSImageToSkBitmapWithColorSpace( - NSImage* image, bool is_opaque, CGColorSpaceRef color_space) { - return NSImageOrNSImageRepToSkBitmapWithColorSpace( - image, /*image_rep=*/nil, image.size, is_opaque, color_space); +SkBitmap NSImageToSkBitmap(NSImage* image, bool is_opaque) { + return NSImageOrNSImageRepToSkBitmap(image, /*image_rep=*/nil, image.size, + is_opaque); } -SkBitmap NSImageRepToSkBitmapWithColorSpace(NSImageRep* image_rep, - NSSize size, - bool is_opaque, - CGColorSpaceRef color_space) { - return NSImageOrNSImageRepToSkBitmapWithColorSpace( - /*image=*/nil, image_rep, size, is_opaque, color_space); +SkBitmap NSImageRepToSkBitmap(NSImageRep* image_rep, + NSSize size, + bool is_opaque) { + return NSImageOrNSImageRepToSkBitmap( + /*image=*/nil, image_rep, size, is_opaque); } -NSBitmapImageRep* SkBitmapToNSBitmapImageRepWithColorSpace( - const SkBitmap& skiaBitmap, - CGColorSpaceRef colorSpace) { +NSBitmapImageRep* SkBitmapToNSBitmapImageRep(const SkBitmap& skiaBitmap) { // First convert SkBitmap to CGImageRef. base::apple::ScopedCFTypeRef<CGImageRef> cgimage( - SkCreateCGImageRefWithColorspace(skiaBitmap, colorSpace)); + SkCreateCGImageRef(skiaBitmap)); if (!cgimage) return nil; @@ -237,14 +269,12 @@ return [[NSBitmapImageRep alloc] initWithCGImage:cgimage.get()]; } -NSImage* SkBitmapToNSImageWithColorSpace(const SkBitmap& skiaBitmap, - CGColorSpaceRef colorSpace) { +NSImage* SkBitmapToNSImage(const SkBitmap& skiaBitmap) { if (skiaBitmap.isNull()) return nil; NSImage* image = [[NSImage alloc] init]; - NSBitmapImageRep* imageRep = - SkBitmapToNSBitmapImageRepWithColorSpace(skiaBitmap, colorSpace); + NSBitmapImageRep* imageRep = SkBitmapToNSBitmapImageRep(skiaBitmap); if (!imageRep) return nil; [image addRepresentation:imageRep];
diff --git a/skia/ext/skia_utils_mac_unittest.mm b/skia/ext/skia_utils_mac_unittest.mm index 1470ba6..a9a26c46 100644 --- a/skia/ext/skia_utils_mac_unittest.mm +++ b/skia/ext/skia_utils_mac_unittest.mm
@@ -41,8 +41,8 @@ // Checks that the given bitmap is red. void TestSkBitmap(const SkBitmap& bitmap); - // Tests `SkBitmapToNSImageWithColorSpace` for a specific combination of color - // and color type. Creates a bitmap with `CreateSkBitmap`, converts it into an + // Tests `SkBitmapToNSImage` for a specific combination of color and color + // type. Creates a bitmap with `CreateSkBitmap`, converts it into an // `NSImage`, then tests it with `TestImageRep`. void ShapeHelper(int width, int height, @@ -155,8 +155,7 @@ SkBitmap bitmap(CreateSkBitmap(width, height, test_color, color_type)); // Confirm size - NSImage* image = skia::SkBitmapToNSImageWithColorSpace( - bitmap, base::mac::GetSRGBColorSpace()); + NSImage* image = skia::SkBitmapToNSImage(bitmap); EXPECT_DOUBLE_EQ(image.size.width, (CGFloat)width); EXPECT_DOUBLE_EQ(image.size.height, (CGFloat)height); @@ -186,8 +185,7 @@ SkBitmap bitmap( CreateSkBitmap(width, height, TestColor::kBlue, ColorType::k24Bit)); - NSBitmapImageRep* imageRep = skia::SkBitmapToNSBitmapImageRepWithColorSpace( - bitmap, base::mac::GetSRGBColorSpace()); + NSBitmapImageRep* imageRep = skia::SkBitmapToNSBitmapImageRep(bitmap); EXPECT_DOUBLE_EQ(width, imageRep.size.width); EXPECT_DOUBLE_EQ(height, imageRep.size.height); @@ -202,8 +200,7 @@ EXPECT_EQ(1u, image.representations.count); NSBitmapImageRep* imageRep = base::apple::ObjCCastStrict<NSBitmapImageRep>( image.representations.lastObject); - SkBitmap bitmap(skia::NSImageRepToSkBitmapWithColorSpace( - imageRep, image.size, false, base::mac::GetSRGBColorSpace())); + SkBitmap bitmap(skia::NSImageRepToSkBitmap(imageRep, image.size, false)); TestSkBitmap(bitmap); }
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 206eb45..44fc73e 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -6193,9 +6193,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6205,8 +6205,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -6343,9 +6343,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6355,8 +6355,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 1592f11..b135935 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -20593,9 +20593,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20605,8 +20605,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -20743,9 +20743,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20755,8 +20755,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 441debb..28fed8b 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -43432,9 +43432,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43443,8 +43443,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -43582,9 +43582,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43593,8 +43593,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -44906,9 +44906,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44917,8 +44917,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -45056,9 +45056,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45067,8 +45067,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -45766,9 +45766,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45777,8 +45777,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 86d4d7e..3e39298 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -16313,12 +16313,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16328,8 +16328,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": { @@ -16483,12 +16483,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 122.0.6181.0", + "description": "Run with ash-chrome version 122.0.6182.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16498,8 +16498,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v122.0.6181.0", - "revision": "version:122.0.6181.0" + "location": "lacros_version_skew_tests_v122.0.6182.0", + "revision": "version:122.0.6182.0" } ], "dimensions": {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 0eb43b4..0a96cd90 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -337,16 +337,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 122.0.6181.0', + 'description': 'Run with ash-chrome version 122.0.6182.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6181.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v122.0.6182.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v122.0.6181.0', - 'revision': 'version:122.0.6181.0', + 'location': 'lacros_version_skew_tests_v122.0.6182.0', + 'revision': 'version:122.0.6182.0', }, ], },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8d45ba5d..355c4ac 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -20677,6 +20677,25 @@ ] } ], + "WaffleAndroidStudy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "favicon_size_in_dip": "32" + }, + "enable_features": [ + "LargeFaviconFromGoogle", + "SearchEngineChoice" + ] + } + ] + } + ], "WaffleStudy": [ { "platforms": [
diff --git a/third_party/android_toolchain/3pp/install.sh b/third_party/android_toolchain/3pp/install.sh index 224463ec..5438512ec 100755 --- a/third_party/android_toolchain/3pp/install.sh +++ b/third_party/android_toolchain/3pp/install.sh
@@ -48,5 +48,5 @@ # Remove excluded files from the staging directory. for pattern in "${GLOB_EXCLUDES[@]}"; do - rm -rf $pattern + rm -rf "${PREFIX}/${pattern}" done
diff --git a/third_party/android_toolchain_canary/3pp/install.sh b/third_party/android_toolchain_canary/3pp/install.sh index d6f7c1c..50ece3c 100755 --- a/third_party/android_toolchain_canary/3pp/install.sh +++ b/third_party/android_toolchain_canary/3pp/install.sh
@@ -50,5 +50,5 @@ # Remove excluded files from the staging directory. for pattern in "${GLOB_EXCLUDES[@]}"; do - rm -rf $pattern + rm -rf "${PREFIX}/${pattern}" done
diff --git a/third_party/angle b/third_party/angle index 35e49df..bdd3a77 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 35e49df77d01932715b8cd8dd3e1613cbd476561 +Subproject commit bdd3a778370b833bb91659971efa001c584900a8
diff --git a/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom b/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom index de7d10f..87e985c3 100644 --- a/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom +++ b/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom
@@ -5,6 +5,7 @@ module blink.mojom; import "mojo/public/mojom/base/byte_string.mojom"; +import "mojo/public/mojom/base/time.mojom"; import "url/mojom/url.mojom"; // Interface for LCP Critical Path Predictor from the renderer process. @@ -27,6 +28,14 @@ // - and the `font_url` scheme is HTTP or HTTPS, // Otherwise, the renderer will be killed. NotifyFetchedFont(url.mojom.Url font_url); + + // This method is for letting the LCPP know the subresource URL. This + // method should be called under the following conditions: + // - the `kHttpDiskCachePrewarming` feature is enabled, + // - and the `subresource_url` scheme is HTTP or HTTPS, + // Otherwise, the renderer will be killed. + // 'subresource_load_start' is the duration from navigation start to resource loading start time. + NotifyFetchedSubresource(url.mojom.Url subresource_url, mojo_base.mojom.TimeDelta subresource_load_start); }; // LCP Critical Path Predictor hints provided at navigation time.
diff --git a/third_party/blink/public/mojom/printing/web_printing.mojom b/third_party/blink/public/mojom/printing/web_printing.mojom index e683c27c..5b501d5 100644 --- a/third_party/blink/public/mojom/printing/web_printing.mojom +++ b/third_party/blink/public/mojom/printing/web_printing.mojom
@@ -17,6 +17,11 @@ kTwoSidedShortEdge }; +enum WebPrintColorMode { + kColor, + kMonochrome +}; + // Basic description of a single printer. struct WebPrinterInfo { string printer_name; @@ -36,6 +41,9 @@ WebPrintingMultipleDocumentHandling multiple_document_handling_default; array<WebPrintingMultipleDocumentHandling> multiple_document_handling_supported; + WebPrintColorMode print_color_mode_default; + array<WebPrintColorMode> print_color_mode_supported; + WebPrintingSides? sides_default; array<WebPrintingSides> sides_supported; }; @@ -45,6 +53,7 @@ uint32 copies; WebPrintingMultipleDocumentHandling? multiple_document_handling; + WebPrintColorMode? print_color_mode; WebPrintingSides? sides; };
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h index 6219ead..2ba868f0 100644 --- a/third_party/blink/public/web/web_view.h +++ b/third_party/blink/public/web/web_view.h
@@ -478,6 +478,11 @@ // Returns whether this WebView represents a fenced frame root or not. virtual bool IsFencedFrameRoot() const = 0; + // Draggable Regions --------------------------------------------------- + // Indicates that this WebView should collect draggable regions set using the + // app-region CSS property. + virtual void SetSupportsAppRegion(bool supports_app_region) = 0; + // Misc ------------------------------------------------------------- // Returns the number of live WebView instances in this process.
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 84a86ff..18590589 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -3118,6 +3118,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_resolution_units.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_sides.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_printing_sides.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_print_color_mode.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_print_color_mode.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_print_job_state.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_print_job_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_print_quality.cc",
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index a6ed7ad1..1578648 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1495,6 +1495,9 @@ sources += rebase_path(blink_core_tests_intersection_observer, "", "intersection_observer") + sources += rebase_path(blink_core_tests_lcp_critical_path_predictor, + "", + "lcp_critical_path_predictor") sources += rebase_path(blink_core_tests_mathml, "", "mathml") sources += rebase_path(blink_core_tests_messaging, "", "messaging") sources += rebase_path(blink_core_tests_mobile_metrics, "", "mobile_metrics")
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 738c251..77d5462 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -7034,6 +7034,7 @@ } TEST_F(StyleEngineTest, EnsureAppRegionTriggersRelayout) { + GetDocument().GetFrame()->SetSupportsAppRegion(true); GetDocument().body()->setInnerHTML(R"HTML( <head> <style>
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index adb1c7c..81a6dbe 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3988,6 +3988,10 @@ return GetPage()->IsMainFrameFencedFrameRoot(); } +void WebViewImpl::SetSupportsAppRegion(bool supports_app_region) { + MainFrameImpl()->GetFrame()->SetSupportsAppRegion(supports_app_region); +} + void WebViewImpl::MojoDisconnected() { #if !(BUILDFLAG(IS_ANDROID) || \ (BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_ARM64)))
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index 5a99921..3aeffb1 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -241,6 +241,7 @@ int32_t HistoryListLength() const { return history_list_length_; } const SessionStorageNamespaceId& GetSessionStorageNamespaceId() override; bool IsFencedFrameRoot() const override; + void SetSupportsAppRegion(bool supports_app_region) override; // Functions to add and remove observers for this object. void AddObserver(WebViewObserver* observer);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 4bbd11e8..a2d66e8 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -3827,4 +3827,19 @@ return loader_.GetDocumentLoader()->GetContentSettings(); } +bool LocalFrame::SupportsAppRegion() { + return supports_app_region_; +} + +void LocalFrame::SetSupportsAppRegion(bool supports_app_region) { + supports_app_region_ = supports_app_region; + if (supports_app_region) { + view_->UpdateDocumentAnnotatedRegions(); + } else { + CHECK(GetDocument()); + GetDocument()->SetAnnotatedRegions(Vector<AnnotatedRegionValue>()); + Client()->AnnotatedRegionsChanged(); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 534393e..6e19d55 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -925,6 +925,10 @@ // Can only be called while the frame is not detached. const mojom::RendererContentSettingsPtr& GetContentSettings(); + // Returns true if the frame supports app-region: drag/no-drag. + bool SupportsAppRegion(); + void SetSupportsAppRegion(bool supports_app_region); + private: friend class FrameNavigationDisabler; // LocalFrameMojoHandler is a part of LocalFrame. @@ -1186,6 +1190,8 @@ Member<v8_compile_hints::V8LocalCompileHintsProducer> v8_local_compile_hints_producer_; + + bool supports_app_region_ = false; }; inline FrameLoader& LocalFrame::Loader() const {
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 91dba0ae..3016bc66 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1747,8 +1747,10 @@ void LocalFrameView::UpdateDocumentAnnotatedRegions() const { Document* document = frame_->GetDocument(); - if (!document->HasAnnotatedRegions()) + if (!document->HasAnnotatedRegions() || !frame_->SupportsAppRegion()) { return; + } + Vector<AnnotatedRegionValue> new_regions; CollectAnnotatedRegions(*(document->GetLayoutBox()), new_regions); if (new_regions == document->AnnotatedRegions())
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index 9bd131b..d851151 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -100,6 +100,8 @@ kResetForTesting, }; +const char kHistogramScanAndPreloadTime[] = "Blink.ScanAndPreloadTime2"; + bool ThreadedPreloadScannerEnabled( FeatureResetMode reset_mode = FeatureResetMode::kUseCached) { // Cache the feature value since checking for each parser regresses some micro @@ -1346,12 +1348,27 @@ void HTMLDocumentParser::ScanAndPreload(HTMLPreloadScanner* scanner) { TRACE_EVENT0("blink", "HTMLDocumentParser::ScanAndPreload"); - DCHECK(preloader_); - base::ElapsedTimer timer; - ProcessPreloadData(scanner->Scan(GetDocument()->ValidBaseElementURL())); + CHECK(preloader_); + base::ElapsedTimer timer_before_scan; + std::unique_ptr<PendingPreloadData> preload_data = + scanner->Scan(GetDocument()->ValidBaseElementURL()); + base::UmaHistogramMicrosecondsTimes( + base::StrCat( + {kHistogramScanAndPreloadTime, ".Scan", GetPreloadHistogramSuffix()}), + timer_before_scan.Elapsed()); + base::ElapsedTimer timer_after_scan; + ProcessPreloadData(std::move(preload_data)); + base::UmaHistogramMicrosecondsTimes( + base::StrCat({kHistogramScanAndPreloadTime, GetPreloadHistogramSuffix()}), + timer_before_scan.Elapsed()); + // Keep old histogram until next expiry date. base::UmaHistogramTimes( base::StrCat({"Blink.ScanAndPreloadTime", GetPreloadHistogramSuffix()}), - timer.Elapsed()); + timer_before_scan.Elapsed()); + base::UmaHistogramMicrosecondsTimes( + base::StrCat({kHistogramScanAndPreloadTime, ".Preload", + GetPreloadHistogramSuffix()}), + timer_after_scan.Elapsed()); } void HTMLDocumentParser::ProcessPreloadData(
diff --git a/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc b/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc index 76c494d..a72a1e2 100644 --- a/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc +++ b/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc
@@ -228,8 +228,7 @@ base::TimeTicks::Now() - document->Loader()->GetTiming().NavigationStart(); CHECK_GE(resource_load_start, base::Seconds(0)); - // TODO(chikamune): Send url and resource_load_start to browser. - NOTIMPLEMENTED(); + GetHost().NotifyFetchedSubresource(url, resource_load_start); } mojom::blink::LCPCriticalPathPredictorHost&
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc index 7337cee..30818d9 100644 --- a/third_party/blink/renderer/core/loader/preload_helper.cc +++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/loader/preload_helper.h" +#include "base/metrics/histogram_functions.h" +#include "base/timer/elapsed_timer.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" @@ -909,6 +911,8 @@ Resource* PreloadHelper::StartPreload(ResourceType type, FetchParameters& params, Document& document) { + base::ElapsedTimer timer; + ResourceFetcher* resource_fetcher = document.Fetcher(); Resource* resource = nullptr; switch (type) { @@ -967,6 +971,9 @@ NOTREACHED(); } + base::UmaHistogramMicrosecondsTimes("Blink.PreloadRequestStartDuration", + timer.Elapsed()); + return resource; }
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc index afc0d9e1..787f139 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.cc +++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -4,23 +4,7 @@ #include "third_party/blink/renderer/core/paint/background_image_geometry.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/layout/fragmentation_utils.h" -#include "third_party/blink/renderer/core/layout/layout_box.h" -#include "third_party/blink/renderer/core/layout/layout_box_model_object.h" -#include "third_party/blink/renderer/core/layout/layout_view.h" -#include "third_party/blink/renderer/core/layout/physical_box_fragment.h" -#include "third_party/blink/renderer/core/layout/table/layout_table_cell.h" #include "third_party/blink/renderer/core/paint/paint_info.h" -#include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" -#include "third_party/blink/renderer/core/paint/rounded_border_geometry.h" -#include "third_party/blink/renderer/core/style/border_edge.h" -#include "third_party/blink/renderer/platform/geometry/layout_rect.h" -#include "third_party/blink/renderer/platform/geometry/layout_unit.h" -#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" namespace blink { @@ -221,243 +205,31 @@ void BackgroundImageGeometry::UseFixedAttachment( const PhysicalOffset& attachment_point) { - DCHECK(has_background_fixed_to_viewport_); PhysicalOffset fixed_adjustment = attachment_point - unsnapped_dest_rect_.offset; fixed_adjustment.ClampNegativeToZero(); phase_ += fixed_adjustment; } -bool BackgroundImageGeometry::ShouldUseFixedAttachment( - const FillLayer& fill_layer) const { - // Only backgrounds fixed to viewport should be treated as fixed attachment. - // See comments in the private constructor. - return has_background_fixed_to_viewport_ && - // Solid color background should use default attachment. - fill_layer.GetImage() && - fill_layer.Attachment() == EFillAttachment::kFixed; -} - -bool BackgroundImageGeometry::CanCompositeBackgroundAttachmentFixed() const { - return !painting_view_ && has_background_fixed_to_viewport_ && - positioning_box_->CanCompositeBackgroundAttachmentFixed(); -} - -PhysicalRect BackgroundImageGeometry::FixedAttachmentPositioningArea( - const PaintInfo& paint_info) const { - const ScrollableArea* layout_viewport = - box_->GetFrameView()->LayoutViewport(); - DCHECK(layout_viewport); - PhysicalSize size(layout_viewport->VisibleContentRect().size()); - if (CanCompositeBackgroundAttachmentFixed()) { - // The caller should have adjusted paint chunk properties to be in the - // viewport space. - return PhysicalRect(PhysicalOffset(), size); - } - gfx::PointF viewport_origin_in_local_space = - GeometryMapper::SourceToDestinationProjection( - box_->View()->FirstFragment().LocalBorderBoxProperties().Transform(), - paint_info.context.GetPaintController() - .CurrentPaintChunkProperties() - .Transform()) - .MapPoint(gfx::PointF()); - return PhysicalRect( - PhysicalOffset::FromPointFRound(viewport_origin_in_local_space), - PhysicalSize(layout_viewport->VisibleContentRect().size())); -} - -namespace { - -// Computes the stitched table-grid rect relative to the current fragment. -PhysicalRect ComputeStitchedTableGridRect(const PhysicalBoxFragment& fragment) { - const auto writing_direction = fragment.Style().GetWritingDirection(); - LogicalRect table_grid_rect; - LogicalRect fragment_local_grid_rect; - LayoutUnit stitched_block_size; - - for (const PhysicalBoxFragment& walker : - To<LayoutBox>(fragment.GetLayoutObject())->PhysicalFragments()) { - LogicalRect local_grid_rect = walker.TableGridRect(); - local_grid_rect.offset.block_offset += stitched_block_size; - if (table_grid_rect.IsEmpty()) - table_grid_rect = local_grid_rect; - else - table_grid_rect.Unite(local_grid_rect); - - if (&walker == &fragment) - fragment_local_grid_rect = local_grid_rect; - - stitched_block_size += - LogicalFragment(writing_direction, walker).BlockSize(); - } - - // Make the rect relative to the fragment we are currently painting. - table_grid_rect.offset.block_offset -= - fragment_local_grid_rect.offset.block_offset; - - WritingModeConverter converter( - writing_direction, ToPhysicalSize(fragment_local_grid_rect.size, - writing_direction.GetWritingMode())); - return converter.ToPhysical(table_grid_rect); -} - -} // Anonymous namespace - BackgroundImageGeometry::BackgroundImageGeometry( const LayoutView& view, const PhysicalOffset& element_positioning_area_offset) - : box_(&view), positioning_box_(&view.RootBox()) { - has_background_fixed_to_viewport_ = view.IsBackgroundAttachmentFixedObject(); - painting_view_ = true; - // The background of the box generated by the root element covers the - // entire canvas and will be painted by the view object, but the we should - // still use the root element box for positioning. - positioning_size_override_ = view.RootBox().Size(); - // The background image should paint from the root element's coordinate space. - element_positioning_area_offset_ = element_positioning_area_offset; -} + : paint_context_(view, element_positioning_area_offset) {} BackgroundImageGeometry::BackgroundImageGeometry( const LayoutBoxModelObject& obj) - : BackgroundImageGeometry(&obj, &obj) {} + : paint_context_(obj) {} // TablesNG background painting. BackgroundImageGeometry::BackgroundImageGeometry(const LayoutTableCell& cell, PhysicalOffset cell_offset, const LayoutBox& table_part, PhysicalSize table_part_size) - : BackgroundImageGeometry(&cell, &table_part) { - painting_table_cell_ = true; - cell_using_container_background_ = true; - element_positioning_area_offset_ = cell_offset; - positioning_size_override_ = table_part_size; -} + : paint_context_(cell, cell_offset, table_part, table_part_size) {} BackgroundImageGeometry::BackgroundImageGeometry( const PhysicalBoxFragment& fragment) - : BackgroundImageGeometry( - To<LayoutBoxModelObject>(fragment.GetLayoutObject()), - To<LayoutBoxModelObject>(fragment.GetLayoutObject())) { - DCHECK(box_->IsBox()); - - if (fragment.IsTable()) { - auto stitched_background_rect = ComputeStitchedTableGridRect(fragment); - positioning_size_override_ = stitched_background_rect.size; - element_positioning_area_offset_ = -stitched_background_rect.offset; - box_has_multiple_fragments_ = !fragment.IsOnlyForNode(); - } else if (!fragment.IsOnlyForNode()) { - // The element is block-fragmented. We need to calculate the correct - // background offset within an imaginary box where all the fragments have - // been stitched together. - element_positioning_area_offset_ = - OffsetInStitchedFragments(fragment, &positioning_size_override_); - box_has_multiple_fragments_ = true; - } -} - -BackgroundImageGeometry::BackgroundImageGeometry( - const LayoutBoxModelObject* box, - const LayoutBoxModelObject* positioning_box) - : box_(box), - positioning_box_(positioning_box), - has_background_fixed_to_viewport_( - HasBackgroundFixedToViewport(*positioning_box)) { - // Specialized constructor should be used for LayoutView. - DCHECK(!IsA<LayoutView>(box)); - DCHECK(box); - DCHECK(positioning_box); -} - -PhysicalBoxStrut BackgroundImageGeometry::VisualOverflowOutsets() const { - PhysicalRect border_box; - if (positioning_box_->IsBox()) { - border_box = To<LayoutBox>(positioning_box_)->PhysicalBorderBoxRect(); - } else { - border_box = To<LayoutInline>(positioning_box_)->PhysicalLinesBoundingBox(); - } - PhysicalRect visual_overflow = - positioning_box_->Layer() - ->LocalBoundingBoxIncludingSelfPaintingDescendants(); - return PhysicalBoxStrut(visual_overflow.Y() - border_box.Y(), - border_box.Right() - visual_overflow.Right(), - border_box.Bottom() - visual_overflow.Bottom(), - visual_overflow.X() - border_box.X()); -} - -PhysicalBoxStrut BackgroundImageGeometry::InnerBorderOutsets( - const PhysicalRect& dest_rect, - const PhysicalRect& positioning_area) const { - gfx::RectF inner_border_rect = - RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( - positioning_box_->StyleRef(), positioning_area) - .Rect(); - PhysicalBoxStrut outset; - // TODO(rendering-core) The LayoutUnit(float) constructor always rounds - // down. We should FromFloatFloor or FromFloatCeil to move toward the border. - outset.left = LayoutUnit(inner_border_rect.x()) - dest_rect.X(); - outset.top = LayoutUnit(inner_border_rect.y()) - dest_rect.Y(); - outset.right = dest_rect.Right() - LayoutUnit(inner_border_rect.right()); - outset.bottom = dest_rect.Bottom() - LayoutUnit(inner_border_rect.bottom()); - return outset; -} - -SnappedAndUnsnappedOutsets BackgroundImageGeometry::ObscuredBorderOutsets( - const PhysicalRect& dest_rect, - const PhysicalRect& positioning_area) const { - const ComputedStyle& style = positioning_box_->StyleRef(); - gfx::RectF inner_border_rect = - RoundedBorderGeometry::PixelSnappedRoundedInnerBorder(style, - positioning_area) - .Rect(); - - BorderEdge edges[4]; - style.GetBorderEdgeInfo(edges); - const PhysicalBoxStrut box_outsets = positioning_box_->BorderOutsets(); - SnappedAndUnsnappedOutsets adjust; - if (edges[static_cast<unsigned>(BoxSide::kTop)].ObscuresBackground()) { - adjust.snapped.top = LayoutUnit(inner_border_rect.y()) - dest_rect.Y(); - adjust.unsnapped.top = box_outsets.top; - } - if (edges[static_cast<unsigned>(BoxSide::kRight)].ObscuresBackground()) { - adjust.snapped.right = - dest_rect.Right() - LayoutUnit(inner_border_rect.right()); - adjust.unsnapped.right = box_outsets.right; - } - if (edges[static_cast<unsigned>(BoxSide::kBottom)].ObscuresBackground()) { - adjust.snapped.bottom = - dest_rect.Bottom() - LayoutUnit(inner_border_rect.bottom()); - adjust.unsnapped.bottom = box_outsets.bottom; - } - if (edges[static_cast<unsigned>(BoxSide::kLeft)].ObscuresBackground()) { - adjust.snapped.left = LayoutUnit(inner_border_rect.x()) - dest_rect.X(); - adjust.unsnapped.left = box_outsets.left; - } - return adjust; -} - -bool BackgroundImageGeometry::HasBackgroundFixedToViewport( - const LayoutBoxModelObject& object) { - if (!object.IsBackgroundAttachmentFixedObject()) { - return false; - } - // https://www.w3.org/TR/css-transforms-1/#transform-rendering - // Fixed backgrounds on the root element are affected by any transform - // specified for that element. For all other elements that are effected - // by a transform, a value of fixed for the background-attachment property - // is treated as if it had a value of scroll. - for (const PaintLayer* layer = object.EnclosingLayer(); - layer && !layer->IsRootLayer(); layer = layer->Parent()) { - // Check LayoutObject::HasTransformRelatedProperty() first to exclude - // non-applicable transforms and will-change: transform. - LayoutObject& ancestor = layer->GetLayoutObject(); - if (ancestor.HasTransformRelatedProperty() && - (layer->Transform() || - ancestor.StyleRef().HasWillChangeHintForAnyTransformProperty())) { - return false; - } - } - return true; -} + : paint_context_(fragment) {} SnappedAndUnsnappedOutsets BackgroundImageGeometry::ComputeDestRectAdjustments( const FillLayer& fill_layer, @@ -466,7 +238,7 @@ SnappedAndUnsnappedOutsets dest_adjust; switch (fill_layer.Clip()) { case EFillBox::kNoClip: - dest_adjust.unsnapped = VisualOverflowOutsets(); + dest_adjust.unsnapped = paint_context_.VisualOverflowOutsets(); dest_adjust.snapped = dest_adjust.unsnapped; break; case EFillBox::kFillBox: @@ -476,24 +248,24 @@ case EFillBox::kContent: // If the PaddingOutsets are zero then this is equivalent to // kPadding and we should apply the snapping logic. - dest_adjust.unsnapped = positioning_box_->PaddingOutsets(); + dest_adjust.unsnapped = paint_context_.PaddingOutsets(); if (!dest_adjust.unsnapped.IsZero()) { - dest_adjust.unsnapped += positioning_box_->BorderOutsets(); + dest_adjust.unsnapped += paint_context_.BorderOutsets(); // We're not trying to match a border position, so don't snap. dest_adjust.snapped = dest_adjust.unsnapped; break; } [[fallthrough]]; case EFillBox::kPadding: - dest_adjust.unsnapped = positioning_box_->BorderOutsets(); + dest_adjust.unsnapped = paint_context_.BorderOutsets(); if (disallow_border_derived_adjustment) { // Nothing to drive snapping behavior, so don't snap. dest_adjust.snapped = dest_adjust.unsnapped; } else { // Force the snapped dest rect to match the inner border to // avoid gaps between the background and border. - dest_adjust.snapped = InnerBorderOutsets(unsnapped_dest_rect_, - unsnapped_positioning_area); + dest_adjust.snapped = paint_context_.InnerBorderOutsets( + unsnapped_dest_rect_, unsnapped_positioning_area); } break; case EFillBox::kStrokeBox: @@ -519,8 +291,8 @@ // the size and position of the borders, sometimes adjusting the inner // border by more than a pixel when done (particularly under magnifying // zoom). - dest_adjust = ObscuredBorderOutsets(unsnapped_dest_rect_, - unsnapped_positioning_area); + dest_adjust = paint_context_.ObscuredBorderOutsets( + unsnapped_dest_rect_, unsnapped_positioning_area); break; } case EFillBox::kText: @@ -543,16 +315,16 @@ case EFillBox::kContent: // If the PaddingOutsets are zero then this is equivalent to // kPadding and we should apply the snapping logic. - box_outset.unsnapped = positioning_box_->PaddingOutsets(); + box_outset.unsnapped = paint_context_.PaddingOutsets(); if (!box_outset.unsnapped.IsZero()) { - box_outset.unsnapped += positioning_box_->BorderOutsets(); + box_outset.unsnapped += paint_context_.BorderOutsets(); // We're not trying to match a border position, so don't snap. box_outset.snapped = box_outset.unsnapped; break; } [[fallthrough]]; case EFillBox::kPadding: - box_outset.unsnapped = positioning_box_->BorderOutsets(); + box_outset.unsnapped = paint_context_.BorderOutsets(); if (disallow_border_derived_adjustment) { box_outset.snapped = box_outset.unsnapped; } else { @@ -562,8 +334,8 @@ // the size and position of the borders, sometimes adjusting the inner // border by more than a pixel when done (particularly under magnifying // zoom). - box_outset.snapped = InnerBorderOutsets(unsnapped_positioning_area, - unsnapped_positioning_area); + box_outset.snapped = paint_context_.InnerBorderOutsets( + unsnapped_positioning_area, unsnapped_positioning_area); } break; case EFillBox::kStrokeBox: @@ -582,20 +354,6 @@ return box_outset; } -PhysicalRect BackgroundImageGeometry::ComputePositioningArea( - const PaintInfo& paint_info, - const FillLayer& fill_layer, - const PhysicalRect& paint_rect) const { - if (ShouldUseFixedAttachment(fill_layer)) { - return FixedAttachmentPositioningArea(paint_info); - } - if (painting_view_ || cell_using_container_background_ || - box_has_multiple_fragments_) { - return {PhysicalOffset(), positioning_size_override_}; - } - return paint_rect; -} - void BackgroundImageGeometry::AdjustPositioningArea( const PaintInfo& paint_info, const FillLayer& fill_layer, @@ -604,7 +362,7 @@ PhysicalRect& snapped_positioning_area, PhysicalOffset& unsnapped_box_offset, PhysicalOffset& snapped_box_offset) { - if (ShouldUseFixedAttachment(fill_layer)) { + if (paint_context_.ShouldUseFixedAttachment(fill_layer)) { unsnapped_dest_rect_ = snapped_dest_rect_ = snapped_positioning_area = unsnapped_positioning_area; } else { @@ -635,10 +393,7 @@ bool disallow_border_derived_adjustment = !ShouldPaintSelfBlockBackground(paint_info.phase) || fill_layer.Composite() != CompositeOperator::kCompositeSourceOver || - painting_view_ || painting_table_cell_ || box_has_multiple_fragments_ || - positioning_box_->StyleRef().BorderImage().GetImage() || - positioning_box_->StyleRef().BorderCollapse() == - EBorderCollapse::kCollapse; + paint_context_.DisallowBorderDerivedAdjustment(); // Compute all the outsets we need to apply to the rectangles. These // outsets also include the snapping behavior. @@ -679,14 +434,14 @@ const PhysicalSize& snapped_positioning_area_size) { StyleImage* image = fill_layer.GetImage(); EFillSizeType type = fill_layer.SizeType(); + const ComputedStyle& style = paint_context_.Style(); // Tile size is snapped for images without intrinsic dimensions (typically // generated content) and unsnapped for content that has intrinsic // dimensions. Once we choose here we stop tracking whether the tile size is // snapped or unsnapped. - IntrinsicSizingInfo sizing_info = - image->GetNaturalSizingInfo(positioning_box_->StyleRef().EffectiveZoom(), - box_->StyleRef().ImageOrientation()); + IntrinsicSizingInfo sizing_info = image->GetNaturalSizingInfo( + style.EffectiveZoom(), style.ImageOrientation()); PhysicalSize image_aspect_ratio = PhysicalSize::FromSizeFFloor(sizing_info.aspect_ratio); PhysicalSize positioning_area_size = !image->HasIntrinsicSize() @@ -742,10 +497,10 @@ tile_size_.height = positioning_area_size.height; } } else if (layer_width.IsAuto() && layer_height.IsAuto()) { - PhysicalSize concrete_image_size = PhysicalSize::FromSizeFFloor( - image->ImageSize(positioning_box_->StyleRef().EffectiveZoom(), - gfx::SizeF(positioning_area_size), - box_->StyleRef().ImageOrientation())); + PhysicalSize concrete_image_size = + PhysicalSize::FromSizeFFloor(image->ImageSize( + style.EffectiveZoom(), gfx::SizeF(positioning_area_size), + style.ImageOrientation())); tile_size_ = concrete_image_size; } @@ -915,14 +670,11 @@ void BackgroundImageGeometry::Calculate(const PaintInfo& paint_info, const FillLayer& fill_layer, const PhysicalRect& paint_rect) { - DCHECK_GE(box_->GetDocument().Lifecycle().GetState(), - DocumentLifecycle::kPrePaintClean); - // Unsnapped positioning area is used to derive quantities // that reference source image maps and define non-integer values, such // as phase and position. PhysicalRect unsnapped_positioning_area = - ComputePositioningArea(paint_info, fill_layer, paint_rect); + paint_context_.ComputePositioningArea(paint_info, fill_layer, paint_rect); // Snapped positioning area is used for sizing images based on the // background area (like cover and contain), and for setting the repeat @@ -943,13 +695,15 @@ snapped_positioning_area.size); // Applies *-repeat and *-position. - const PhysicalOffset offset_in_background = OffsetInBackground(fill_layer); + const PhysicalOffset offset_in_background = + paint_context_.OffsetInBackground(fill_layer); CalculateRepeatAndPosition( fill_layer, offset_in_background, unsnapped_positioning_area.size, snapped_positioning_area.size, unsnapped_box_offset, snapped_box_offset); - if (ShouldUseFixedAttachment(fill_layer)) + if (paint_context_.ShouldUseFixedAttachment(fill_layer)) { UseFixedAttachment(paint_rect.offset); + } // The actual painting area can be bigger than the provided background // geometry (`paint_rect`) for `mask-clip: no-clip`, so avoid clipping. @@ -962,24 +716,6 @@ snapped_dest_rect_ = PhysicalRect(ToPixelSnappedRect(snapped_dest_rect_)); } -const ImageResourceObserver& BackgroundImageGeometry::ImageClient() const { - return *(painting_view_ ? box_ : positioning_box_); -} - -const ComputedStyle& BackgroundImageGeometry::ImageStyle( - const ComputedStyle& fragment_style) const { - if (painting_view_ || cell_using_container_background_) - return positioning_box_->StyleRef(); - return fragment_style; -} - -PhysicalOffset BackgroundImageGeometry::OffsetInBackground( - const FillLayer& fill_layer) const { - if (ShouldUseFixedAttachment(fill_layer)) - return PhysicalOffset(); - return element_positioning_area_offset_; -} - PhysicalOffset BackgroundImageGeometry::ComputePhase() const { // Given the size that the whole image should draw at, and the input phase // requested by the content, and the space between repeated tiles, compute a
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.h b/third_party/blink/renderer/core/paint/background_image_geometry.h index cd36d3d..f764ff4 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.h +++ b/third_party/blink/renderer/core/paint/background_image_geometry.h
@@ -6,15 +6,12 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BACKGROUND_IMAGE_GEOMETRY_H_ #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" -#include "third_party/blink/renderer/core/paint/paint_phase.h" -#include "third_party/blink/renderer/platform/graphics/graphics_types.h" +#include "third_party/blink/renderer/core/paint/box_background_paint_context.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { -class ComputedStyle; class FillLayer; -class ImageResourceObserver; class LayoutBox; class LayoutBoxModelObject; class LayoutTableCell; @@ -22,11 +19,6 @@ class PhysicalBoxFragment; struct PaintInfo; -struct SnappedAndUnsnappedOutsets { - PhysicalBoxStrut snapped; - PhysicalBoxStrut unsnapped; -}; - class BackgroundImageGeometry { STACK_ALLOCATED(); @@ -47,12 +39,6 @@ explicit BackgroundImageGeometry(const PhysicalBoxFragment&); - // Compute the initial position area based on the geometry for the object - // this BackgroundImageGeometry was created for. - PhysicalRect ComputePositioningArea(const PaintInfo& paint_info, - const FillLayer& fill_layer, - const PhysicalRect& paint_rect) const; - // Calculates data members. This must be called before any of the following // getters is called. The document lifecycle phase must be at least // PrePaintClean. @@ -60,6 +46,8 @@ const FillLayer&, const PhysicalRect& paint_rect); + const BoxBackgroundPaintContext& GetContext() const { return paint_context_; } + // Destination rects define the area into which the image will paint. // For cases where no explicit background size is requested, the destination // also defines the subset of the image to be drawn. Both border-snapped @@ -93,25 +81,7 @@ // the image if used as a pattern with background-repeat: space. const PhysicalSize& SpaceSize() const { return repeat_spacing_; } - // Whether the background needs to be positioned relative to a container - // element. Only used for tables. - bool CellUsingContainerBackground() const { - return cell_using_container_background_; - } - - const ImageResourceObserver& ImageClient() const; - const ComputedStyle& ImageStyle(const ComputedStyle& fragment_style) const; - - bool CanCompositeBackgroundAttachmentFixed() const; - - static bool HasBackgroundFixedToViewport(const LayoutBoxModelObject&); - private: - BackgroundImageGeometry(const LayoutBoxModelObject* box, - const LayoutBoxModelObject* positioning_box); - - bool ShouldUseFixedAttachment(const FillLayer&) const; - void SetSpaceSize(const PhysicalSize& repeat_spacing) { repeat_spacing_ = repeat_spacing; } @@ -129,7 +99,6 @@ void SetSpaceX(LayoutUnit space, LayoutUnit extra_offset); void SetSpaceY(LayoutUnit space, LayoutUnit extra_offset); - PhysicalRect FixedAttachmentPositioningArea(const PaintInfo&) const; void UseFixedAttachment(const PhysicalOffset& attachment_point); // Compute adjustments for the destination rects. Adjustments @@ -167,53 +136,13 @@ const PhysicalOffset& unsnapped_box_offset, const PhysicalOffset& snapped_box_offset); - PhysicalBoxStrut VisualOverflowOutsets() const; - PhysicalBoxStrut InnerBorderOutsets( - const PhysicalRect& dest_rect, - const PhysicalRect& positioning_area) const; - SnappedAndUnsnappedOutsets ObscuredBorderOutsets( - const PhysicalRect& dest_rect, - const PhysicalRect& positioning_area) const; - - // The offset of the background image within the background positioning area. - PhysicalOffset OffsetInBackground(const FillLayer&) const; - - // In most cases this is the same as positioning_box_. They are different - // when we are painting: - // 1. the view background (box_ is the LayoutView, and positioning_box_ is - // the LayoutView's RootBox()), or - // 2. a table cell using its row/column's background (box_ is the table cell, - // and positioning_box_ is the row/column). - // When they are different: - // - ImageClient() uses box_ if painting view, otherwise positioning_box_; - // - ImageStyle() uses positioning_box_; - // - FillLayers come from box_ if painting view, otherwise positioning_box_. - const LayoutBoxModelObject* const box_; - - // The positioning box is the source of geometric information for positioning - // and sizing the background. It also provides the information listed in the - // comment for box_. - const LayoutBoxModelObject* const positioning_box_; - - // When painting table cells or the view, the positioning area - // differs from the requested paint rect. - PhysicalSize positioning_size_override_; - - // The background image offset from within the background positioning area for - // non-fixed background attachment. Used for table cells and the view, and - // also when an element is block-fragmented. - PhysicalOffset element_positioning_area_offset_; + const BoxBackgroundPaintContext paint_context_; PhysicalRect unsnapped_dest_rect_; PhysicalRect snapped_dest_rect_; PhysicalOffset phase_; PhysicalSize tile_size_; PhysicalSize repeat_spacing_; - bool has_background_fixed_to_viewport_ = false; - bool painting_view_ = false; - bool painting_table_cell_ = false; - bool cell_using_container_background_ = false; - bool box_has_multiple_fragments_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/box_background_paint_context.cc b/third_party/blink/renderer/core/paint/box_background_paint_context.cc new file mode 100644 index 0000000..36760eb --- /dev/null +++ b/third_party/blink/renderer/core/paint/box_background_paint_context.cc
@@ -0,0 +1,312 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/paint/box_background_paint_context.h" + +#include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/layout/fragmentation_utils.h" +#include "third_party/blink/renderer/core/layout/layout_box.h" +#include "third_party/blink/renderer/core/layout/layout_box_model_object.h" +#include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/layout/physical_box_fragment.h" +#include "third_party/blink/renderer/core/layout/table/layout_table_cell.h" +#include "third_party/blink/renderer/core/paint/paint_info.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" +#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "third_party/blink/renderer/core/paint/rounded_border_geometry.h" +#include "third_party/blink/renderer/core/style/border_edge.h" +#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" + +namespace blink { + +namespace { + +// Computes the stitched table-grid rect relative to the current fragment. +PhysicalRect ComputeStitchedTableGridRect(const PhysicalBoxFragment& fragment) { + const auto writing_direction = fragment.Style().GetWritingDirection(); + LogicalRect table_grid_rect; + LogicalRect fragment_local_grid_rect; + LayoutUnit stitched_block_size; + + for (const PhysicalBoxFragment& walker : + To<LayoutBox>(fragment.GetLayoutObject())->PhysicalFragments()) { + LogicalRect local_grid_rect = walker.TableGridRect(); + local_grid_rect.offset.block_offset += stitched_block_size; + if (table_grid_rect.IsEmpty()) { + table_grid_rect = local_grid_rect; + } else { + table_grid_rect.Unite(local_grid_rect); + } + + if (&walker == &fragment) { + fragment_local_grid_rect = local_grid_rect; + } + + stitched_block_size += + LogicalFragment(writing_direction, walker).BlockSize(); + } + + // Make the rect relative to the fragment we are currently painting. + table_grid_rect.offset.block_offset -= + fragment_local_grid_rect.offset.block_offset; + + WritingModeConverter converter( + writing_direction, ToPhysicalSize(fragment_local_grid_rect.size, + writing_direction.GetWritingMode())); + return converter.ToPhysical(table_grid_rect); +} + +} // Anonymous namespace + +BoxBackgroundPaintContext::BoxBackgroundPaintContext( + const LayoutView& view, + const PhysicalOffset& element_positioning_area_offset) + : box_(&view), positioning_box_(&view.RootBox()) { + has_background_fixed_to_viewport_ = view.IsBackgroundAttachmentFixedObject(); + painting_view_ = true; + // The background of the box generated by the root element covers the + // entire canvas and will be painted by the view object, but the we should + // still use the root element box for positioning. + positioning_size_override_ = view.RootBox().Size(); + // The background image should paint from the root element's coordinate space. + element_positioning_area_offset_ = element_positioning_area_offset; +} + +BoxBackgroundPaintContext::BoxBackgroundPaintContext( + const LayoutBoxModelObject& obj) + : BoxBackgroundPaintContext(&obj, &obj) {} + +// TablesNG background painting. +BoxBackgroundPaintContext::BoxBackgroundPaintContext( + const LayoutTableCell& cell, + PhysicalOffset cell_offset, + const LayoutBox& table_part, + PhysicalSize table_part_size) + : BoxBackgroundPaintContext(&cell, &table_part) { + painting_table_cell_ = true; + cell_using_container_background_ = true; + element_positioning_area_offset_ = cell_offset; + positioning_size_override_ = table_part_size; +} + +BoxBackgroundPaintContext::BoxBackgroundPaintContext( + const PhysicalBoxFragment& fragment) + : BoxBackgroundPaintContext( + To<LayoutBoxModelObject>(fragment.GetLayoutObject()), + To<LayoutBoxModelObject>(fragment.GetLayoutObject())) { + DCHECK(box_->IsBox()); + + if (fragment.IsTable()) { + auto stitched_background_rect = ComputeStitchedTableGridRect(fragment); + positioning_size_override_ = stitched_background_rect.size; + element_positioning_area_offset_ = -stitched_background_rect.offset; + box_has_multiple_fragments_ = !fragment.IsOnlyForNode(); + } else if (!fragment.IsOnlyForNode()) { + // The element is block-fragmented. We need to calculate the correct + // background offset within an imaginary box where all the fragments have + // been stitched together. + element_positioning_area_offset_ = + OffsetInStitchedFragments(fragment, &positioning_size_override_); + box_has_multiple_fragments_ = true; + } +} + +BoxBackgroundPaintContext::BoxBackgroundPaintContext( + const LayoutBoxModelObject* box, + const LayoutBoxModelObject* positioning_box) + : box_(box), + positioning_box_(positioning_box), + has_background_fixed_to_viewport_( + HasBackgroundFixedToViewport(*positioning_box)) { + // Specialized constructor should be used for LayoutView. + DCHECK(!IsA<LayoutView>(box)); + DCHECK(box); + DCHECK(positioning_box); +} + +PhysicalBoxStrut BoxBackgroundPaintContext::BorderOutsets() const { + return positioning_box_->BorderOutsets(); +} + +PhysicalBoxStrut BoxBackgroundPaintContext::PaddingOutsets() const { + return positioning_box_->PaddingOutsets(); +} + +PhysicalBoxStrut BoxBackgroundPaintContext::VisualOverflowOutsets() const { + PhysicalRect border_box; + if (positioning_box_->IsBox()) { + border_box = To<LayoutBox>(positioning_box_)->PhysicalBorderBoxRect(); + } else { + border_box = To<LayoutInline>(positioning_box_)->PhysicalLinesBoundingBox(); + } + PhysicalRect visual_overflow = + positioning_box_->Layer() + ->LocalBoundingBoxIncludingSelfPaintingDescendants(); + return PhysicalBoxStrut(visual_overflow.Y() - border_box.Y(), + border_box.Right() - visual_overflow.Right(), + border_box.Bottom() - visual_overflow.Bottom(), + visual_overflow.X() - border_box.X()); +} + +PhysicalBoxStrut BoxBackgroundPaintContext::InnerBorderOutsets( + const PhysicalRect& dest_rect, + const PhysicalRect& positioning_area) const { + gfx::RectF inner_border_rect = + RoundedBorderGeometry::PixelSnappedRoundedInnerBorder( + positioning_box_->StyleRef(), positioning_area) + .Rect(); + PhysicalBoxStrut outset; + // TODO(rendering-core) The LayoutUnit(float) constructor always rounds + // down. We should FromFloatFloor or FromFloatCeil to move toward the border. + outset.left = LayoutUnit(inner_border_rect.x()) - dest_rect.X(); + outset.top = LayoutUnit(inner_border_rect.y()) - dest_rect.Y(); + outset.right = dest_rect.Right() - LayoutUnit(inner_border_rect.right()); + outset.bottom = dest_rect.Bottom() - LayoutUnit(inner_border_rect.bottom()); + return outset; +} + +SnappedAndUnsnappedOutsets BoxBackgroundPaintContext::ObscuredBorderOutsets( + const PhysicalRect& dest_rect, + const PhysicalRect& positioning_area) const { + const ComputedStyle& style = positioning_box_->StyleRef(); + gfx::RectF inner_border_rect = + RoundedBorderGeometry::PixelSnappedRoundedInnerBorder(style, + positioning_area) + .Rect(); + + BorderEdge edges[4]; + style.GetBorderEdgeInfo(edges); + const PhysicalBoxStrut box_outsets = BorderOutsets(); + SnappedAndUnsnappedOutsets adjust; + if (edges[static_cast<unsigned>(BoxSide::kTop)].ObscuresBackground()) { + adjust.snapped.top = LayoutUnit(inner_border_rect.y()) - dest_rect.Y(); + adjust.unsnapped.top = box_outsets.top; + } + if (edges[static_cast<unsigned>(BoxSide::kRight)].ObscuresBackground()) { + adjust.snapped.right = + dest_rect.Right() - LayoutUnit(inner_border_rect.right()); + adjust.unsnapped.right = box_outsets.right; + } + if (edges[static_cast<unsigned>(BoxSide::kBottom)].ObscuresBackground()) { + adjust.snapped.bottom = + dest_rect.Bottom() - LayoutUnit(inner_border_rect.bottom()); + adjust.unsnapped.bottom = box_outsets.bottom; + } + if (edges[static_cast<unsigned>(BoxSide::kLeft)].ObscuresBackground()) { + adjust.snapped.left = LayoutUnit(inner_border_rect.x()) - dest_rect.X(); + adjust.unsnapped.left = box_outsets.left; + } + return adjust; +} + +PhysicalRect BoxBackgroundPaintContext::ComputePositioningArea( + const PaintInfo& paint_info, + const FillLayer& fill_layer, + const PhysicalRect& paint_rect) const { + if (ShouldUseFixedAttachment(fill_layer)) { + return FixedAttachmentPositioningArea(paint_info); + } + if (painting_view_ || cell_using_container_background_ || + box_has_multiple_fragments_) { + return {PhysicalOffset(), positioning_size_override_}; + } + return paint_rect; +} + +bool BoxBackgroundPaintContext::DisallowBorderDerivedAdjustment() const { + return painting_view_ || painting_table_cell_ || + box_has_multiple_fragments_ || + positioning_box_->StyleRef().BorderImage().GetImage() || + positioning_box_->StyleRef().BorderCollapse() == + EBorderCollapse::kCollapse; +} + +bool BoxBackgroundPaintContext::CanCompositeBackgroundAttachmentFixed() const { + return !painting_view_ && has_background_fixed_to_viewport_ && + positioning_box_->CanCompositeBackgroundAttachmentFixed(); +} + +bool BoxBackgroundPaintContext::ShouldUseFixedAttachment( + const FillLayer& fill_layer) const { + // Only backgrounds fixed to viewport should be treated as fixed attachment. + // See comments in the private constructor. + return has_background_fixed_to_viewport_ && + // Solid color background should use default attachment. + fill_layer.GetImage() && + fill_layer.Attachment() == EFillAttachment::kFixed; +} + +bool BoxBackgroundPaintContext::HasBackgroundFixedToViewport( + const LayoutBoxModelObject& object) { + if (!object.IsBackgroundAttachmentFixedObject()) { + return false; + } + // https://www.w3.org/TR/css-transforms-1/#transform-rendering + // Fixed backgrounds on the root element are affected by any transform + // specified for that element. For all other elements that are effected + // by a transform, a value of fixed for the background-attachment property + // is treated as if it had a value of scroll. + for (const PaintLayer* layer = object.EnclosingLayer(); + layer && !layer->IsRootLayer(); layer = layer->Parent()) { + // Check LayoutObject::HasTransformRelatedProperty() first to exclude + // non-applicable transforms and will-change: transform. + LayoutObject& ancestor = layer->GetLayoutObject(); + if (ancestor.HasTransformRelatedProperty() && + (layer->Transform() || + ancestor.StyleRef().HasWillChangeHintForAnyTransformProperty())) { + return false; + } + } + return true; +} + +PhysicalRect BoxBackgroundPaintContext::FixedAttachmentPositioningArea( + const PaintInfo& paint_info) const { + const ScrollableArea* layout_viewport = + box_->GetFrameView()->LayoutViewport(); + DCHECK(layout_viewport); + PhysicalSize size(layout_viewport->VisibleContentRect().size()); + if (CanCompositeBackgroundAttachmentFixed()) { + // The caller should have adjusted paint chunk properties to be in the + // viewport space. + return PhysicalRect(PhysicalOffset(), size); + } + gfx::PointF viewport_origin_in_local_space = + GeometryMapper::SourceToDestinationProjection( + box_->View()->FirstFragment().LocalBorderBoxProperties().Transform(), + paint_info.context.GetPaintController() + .CurrentPaintChunkProperties() + .Transform()) + .MapPoint(gfx::PointF()); + return PhysicalRect( + PhysicalOffset::FromPointFRound(viewport_origin_in_local_space), + PhysicalSize(layout_viewport->VisibleContentRect().size())); +} + +const ComputedStyle& BoxBackgroundPaintContext::Style() const { + return box_->StyleRef(); +} + +const ImageResourceObserver& BoxBackgroundPaintContext::ImageClient() const { + return *(painting_view_ ? box_ : positioning_box_); +} + +const ComputedStyle& BoxBackgroundPaintContext::ImageStyle( + const ComputedStyle& fragment_style) const { + if (painting_view_ || cell_using_container_background_) { + return positioning_box_->StyleRef(); + } + return fragment_style; +} + +PhysicalOffset BoxBackgroundPaintContext::OffsetInBackground( + const FillLayer& fill_layer) const { + if (ShouldUseFixedAttachment(fill_layer)) { + return PhysicalOffset(); + } + return element_positioning_area_offset_; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/box_background_paint_context.h b/third_party/blink/renderer/core/paint/box_background_paint_context.h new file mode 100644 index 0000000..531639c --- /dev/null +++ b/third_party/blink/renderer/core/paint/box_background_paint_context.h
@@ -0,0 +1,129 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_BACKGROUND_PAINT_CONTEXT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_BACKGROUND_PAINT_CONTEXT_H_ + +#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" +#include "third_party/blink/renderer/core/paint/paint_phase.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" + +namespace blink { + +class ComputedStyle; +class FillLayer; +class ImageResourceObserver; +class LayoutBox; +class LayoutBoxModelObject; +class LayoutTableCell; +class LayoutView; +class PhysicalBoxFragment; +struct PaintInfo; + +struct SnappedAndUnsnappedOutsets { + PhysicalBoxStrut snapped; + PhysicalBoxStrut unsnapped; +}; + +// This class contains/describes the state needed to resolve a layer of a +// 'background-image' or 'mask-image'. +class BoxBackgroundPaintContext { + STACK_ALLOCATED(); + + public: + // Constructor for LayoutView where the coordinate space is different. + BoxBackgroundPaintContext( + const LayoutView&, + const PhysicalOffset& element_positioning_area_offset); + + // Generic constructor for all other elements. + explicit BoxBackgroundPaintContext(const LayoutBoxModelObject&); + + // Constructor for TablesNG table parts. + BoxBackgroundPaintContext(const LayoutTableCell& cell, + PhysicalOffset cell_offset, + const LayoutBox& table_part, + PhysicalSize table_part_size); + + explicit BoxBackgroundPaintContext(const PhysicalBoxFragment&); + + // Compute the initial position area based on the geometry for the object + // this BackgroundPaintContext was created for. + PhysicalRect ComputePositioningArea(const PaintInfo& paint_info, + const FillLayer& fill_layer, + const PhysicalRect& paint_rect) const; + + PhysicalBoxStrut BorderOutsets() const; + PhysicalBoxStrut PaddingOutsets() const; + PhysicalBoxStrut VisualOverflowOutsets() const; + + PhysicalBoxStrut InnerBorderOutsets( + const PhysicalRect& dest_rect, + const PhysicalRect& positioning_area) const; + SnappedAndUnsnappedOutsets ObscuredBorderOutsets( + const PhysicalRect& dest_rect, + const PhysicalRect& positioning_area) const; + + // The offset of the background image within the background positioning area. + PhysicalOffset OffsetInBackground(const FillLayer&) const; + + bool DisallowBorderDerivedAdjustment() const; + bool CanCompositeBackgroundAttachmentFixed() const; + bool ShouldUseFixedAttachment(const FillLayer&) const; + + // Whether the background needs to be positioned relative to a container + // element. Only used for tables. + bool CellUsingContainerBackground() const { + return cell_using_container_background_; + } + + const ComputedStyle& Style() const; + + const ImageResourceObserver& ImageClient() const; + const ComputedStyle& ImageStyle(const ComputedStyle& fragment_style) const; + + static bool HasBackgroundFixedToViewport(const LayoutBoxModelObject&); + + private: + BoxBackgroundPaintContext(const LayoutBoxModelObject* box, + const LayoutBoxModelObject* positioning_box); + + PhysicalRect FixedAttachmentPositioningArea(const PaintInfo&) const; + + // In most cases this is the same as positioning_box_. They are different + // when we are painting: + // 1. the view background (box_ is the LayoutView, and positioning_box_ is + // the LayoutView's RootBox()), or + // 2. a table cell using its row/column's background (box_ is the table + // cell, and positioning_box_ is the row/column). + // When they are different: + // - ImageClient() uses box_ if painting view, otherwise positioning_box_; + // - ImageStyle() uses positioning_box_; + // - FillLayers come from box_ if painting view, otherwise positioning_box_. + const LayoutBoxModelObject* const box_; + + // The positioning box is the source of geometric information for positioning + // and sizing the background. It also provides the information listed in the + // comment for box_. + const LayoutBoxModelObject* const positioning_box_; + + // When painting table cells or the view, the positioning area + // differs from the requested paint rect. + PhysicalSize positioning_size_override_; + + // The background image offset from within the background positioning area + // for non-fixed background attachment. Used for table cells and the view, + // and also when an element is block-fragmented. + PhysicalOffset element_positioning_area_offset_; + + bool has_background_fixed_to_viewport_ = false; + bool painting_view_ = false; + bool painting_table_cell_ = false; + bool cell_using_container_background_ = false; + bool box_has_multiple_fragments_ = false; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_BACKGROUND_PAINT_CONTEXT_H_
diff --git a/third_party/blink/renderer/core/paint/box_fragment_painter.cc b/third_party/blink/renderer/core/paint/box_fragment_painter.cc index 86ff75e5..597bf74 100644 --- a/third_party/blink/renderer/core/paint/box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/box_fragment_painter.cc
@@ -1096,7 +1096,7 @@ } if (box.CanCompositeBackgroundAttachmentFixed() && - BackgroundImageGeometry::HasBackgroundFixedToViewport(box)) { + BoxBackgroundPaintContext::HasBackgroundFixedToViewport(box)) { PaintCompositeBackgroundAttachmentFixed(paint_info, background_client, box_decoration_data); if (box_decoration_data.ShouldPaintBorder()) {
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index 4f34fe3..56b6bff 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -813,7 +813,7 @@ DCHECK(info.should_paint_color || info.should_paint_image); // Painting a background image from an ancestor onto a cell is a complex case. - if (geometry.CellUsingContainerBackground()) { + if (geometry.GetContext().CellUsingContainerBackground()) { return false; } // Complex cases not handled on the fast path. @@ -1183,7 +1183,7 @@ composite_op = SkBlendMode::kSrcOver; } - const ComputedStyle& image_style = geometry.ImageStyle(style_); + const ComputedStyle& image_style = geometry.GetContext().ImageStyle(style_); // If the "image" referenced by the FillLayer is an SVG <mask> reference // (and this is a layer for a mask), then repeat, position, clip, origin and @@ -1191,8 +1191,9 @@ if (bg_layer.GetType() == EFillLayerType::kMask) { if (const auto* mask_source = ToMaskSourceIfSVGMask(*fill_layer_info.image)) { - const PhysicalRect positioning_area = geometry.ComputePositioningArea( - paint_info, bg_layer, scrolled_paint_rect); + const PhysicalRect positioning_area = + geometry.GetContext().ComputePositioningArea(paint_info, bg_layer, + scrolled_paint_rect); const gfx::RectF reference_box(gfx::SizeF(positioning_area.size)); const float zoom = image_style.EffectiveZoom(); @@ -1201,15 +1202,18 @@ context.Translate(positioning_area.X().ToFloat(), positioning_area.Y().ToFloat()); SVGMaskPainter::PaintSVGMaskLayer( - context, *mask_source, geometry.ImageClient(), reference_box, zoom, - composite_op, bg_layer.MaskMode() == EFillMaskMode::kMatchSource); + context, *mask_source, geometry.GetContext().ImageClient(), + reference_box, zoom, composite_op, + bg_layer.MaskMode() == EFillMaskMode::kMatchSource); return; } } + DCHECK_GE(document_.Lifecycle().GetState(), + DocumentLifecycle::kPrePaintClean); geometry.Calculate(paint_info, bg_layer, scrolled_paint_rect); - image = fill_layer_info.image->GetImage(geometry.ImageClient(), document_, - image_style, + image = fill_layer_info.image->GetImage(geometry.GetContext().ImageClient(), + document_, image_style, gfx::SizeF(geometry.TileSize())); image_rendering_settings_context.emplace(context, @@ -1235,12 +1239,12 @@ absl::optional<RoundedInnerRectClipper> clip_to_border; if (fill_layer_info.is_rounded_fill) { - DCHECK(!geometry.CanCompositeBackgroundAttachmentFixed()); + DCHECK(!geometry.GetContext().CanCompositeBackgroundAttachmentFixed()); clip_to_border.emplace(context, rect, border_rect); } if (bg_layer.Clip() == EFillBox::kText) { - DCHECK(!geometry.CanCompositeBackgroundAttachmentFixed()); + DCHECK(!geometry.GetContext().CanCompositeBackgroundAttachmentFixed()); PaintFillLayerTextFillBox(paint_info, fill_layer_info, image.get(), composite_op, geometry, rect, scrolled_paint_rect, object_has_multiple_boxes); @@ -1249,7 +1253,7 @@ // We use BackgroundClip paint property when CanFastScrollFixedAttachment(). absl::optional<GraphicsContextStateSaver> background_clip_state_saver; - if (!geometry.CanCompositeBackgroundAttachmentFixed()) { + if (!geometry.GetContext().CanCompositeBackgroundAttachmentFixed()) { switch (bg_layer.Clip()) { case EFillBox::kFillBox: // Spec: For elements with associated CSS layout box, the used values for
diff --git a/third_party/blink/renderer/core/paint/build.gni b/third_party/blink/renderer/core/paint/build.gni index f8ee176f..edf69650 100644 --- a/third_party/blink/renderer/core/paint/build.gni +++ b/third_party/blink/renderer/core/paint/build.gni
@@ -11,6 +11,8 @@ "block_flow_paint_invalidator.h", "block_paint_invalidator.cc", "block_paint_invalidator.h", + "box_background_paint_context.cc", + "box_background_paint_context.h", "box_border_painter.cc", "box_border_painter.h", "box_decoration_data.cc",
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index ef1a788..5e523e8 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -3002,6 +3002,10 @@ return AnnotatedRegions(document, false, exception_state); } +void Internals::SetSupportsAppRegion(bool supports_app_region) { + GetFrame()->SetSupportsAppRegion(supports_app_region); +} + DOMRectList* Internals::AnnotatedRegions(Document* document, bool draggable, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h index efd180ab..1822439 100644 --- a/third_party/blink/renderer/core/testing/internals.h +++ b/third_party/blink/renderer/core/testing/internals.h
@@ -435,6 +435,7 @@ DOMRectList* draggableRegions(Document*, ExceptionState&); DOMRectList* nonDraggableRegions(Document*, ExceptionState&); + void SetSupportsAppRegion(bool supports_app_region); DOMArrayBuffer* serializeObject(v8::Isolate* isolate, const ScriptValue&,
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl index 9feda14..69c1193 100644 --- a/third_party/blink/renderer/core/testing/internals.idl +++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -261,6 +261,11 @@ [RaisesException] DOMRectList draggableRegions(Document document); [RaisesException] DOMRectList nonDraggableRegions(Document document); + // Overrides default behavior to support the app-region CSS property. + // Setting to true enables collection of draggable/non-draggable + // app regions. + void SetSupportsAppRegion(boolean supports_app_regions); + // Returns a string with information about the mouse cursor used at the specified client location. DOMString getCurrentCursorInfo();
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 5130d312..dd178ac 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -1008,6 +1008,7 @@ "//third_party/blink/renderer/core:testing", "//third_party/blink/renderer/core:unit_test_support", "//third_party/blink/renderer/modules/breakout_box:unit_tests", + "//third_party/blink/renderer/modules/file_system_access:unit_tests", "//third_party/blink/renderer/modules/gamepad:unit_tests", "//third_party/blink/renderer/modules/hid:unit_tests", "//third_party/blink/renderer/modules/idle:unit_tests",
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc index 78d2a46..d5d3823b 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc
@@ -2280,6 +2280,188 @@ } } +struct InstanceNormalizationTester { + OperandInfoBlink input; + struct InstanceNormalizationOptions { + absl::optional<OperandInfoBlink> scale; + absl::optional<OperandInfoBlink> bias; + absl::optional<float> epsilon; + absl::optional<blink::V8MLInputOperandLayout::Enum> layout; + }; + struct InstanceNormalizationAttributes { + absl::optional<OperandInfoMojo> scale; + absl::optional<OperandInfoMojo> bias; + float epsilon = 1e-5; + blink_mojom::InputOperandLayout layout = + blink_mojom::InputOperandLayout::kChannelsFirst; + }; + InstanceNormalizationOptions options; + OperandInfoMojo expected_operand; + InstanceNormalizationAttributes expected_attributes; + + void Test(MLGraphTestMojo& helper, + V8TestingScope& scope, + MLGraphBuilder* builder) { + // Build the graph. + auto* input_operand = + BuildInput(builder, "input", input.dimensions, input.data_type, + scope.GetExceptionState()); + MLInstanceNormalizationOptions* instance_normalization_options = + MLInstanceNormalizationOptions::Create(); + if (options.scale) { + instance_normalization_options->setScale( + BuildInput(builder, "scale", options.scale->dimensions, + options.scale->data_type, scope.GetExceptionState())); + } + if (options.bias) { + instance_normalization_options->setBias( + BuildInput(builder, "bias", options.bias->dimensions, + options.bias->data_type, scope.GetExceptionState())); + } + if (options.epsilon) { + instance_normalization_options->setEpsilon(options.epsilon.value()); + } + if (options.layout) { + instance_normalization_options->setLayout(options.layout.value()); + } + + auto* output_operand = builder->instanceNormalization( + input_operand, instance_normalization_options, + scope.GetExceptionState()); + auto [graph, build_exception] = + helper.BuildGraph(scope, builder, {{"output", output_operand}}); + ASSERT_NE(graph, nullptr); + + auto graph_info = helper.GetGraphInfo(); + // Verify the graph information of mojo are as expected. + ASSERT_EQ(graph_info->operations.size(), 1u); + auto& operation = graph_info->operations[0]; + EXPECT_EQ(operation->is_instance_normalization(), true); + auto& instance_normalization = operation->get_instance_normalization(); + EXPECT_EQ(instance_normalization->layout, expected_attributes.layout); + EXPECT_FLOAT_EQ(instance_normalization->epsilon, + expected_attributes.epsilon); + if (options.scale) { + auto scale_operand_iter = graph_info->id_to_operand_map.find( + instance_normalization->scale_operand_id.value()); + ASSERT_TRUE(scale_operand_iter != graph_info->id_to_operand_map.end()); + EXPECT_EQ(scale_operand_iter->value->data_type, + expected_attributes.scale->data_type); + EXPECT_EQ(scale_operand_iter->value->dimensions, + expected_attributes.scale->dimensions); + } + if (options.bias) { + auto bias_operand_iter = graph_info->id_to_operand_map.find( + instance_normalization->bias_operand_id.value()); + ASSERT_TRUE(bias_operand_iter != graph_info->id_to_operand_map.end()); + EXPECT_EQ(bias_operand_iter->value->data_type, + expected_attributes.bias->data_type); + EXPECT_EQ(bias_operand_iter->value->dimensions, + expected_attributes.bias->dimensions); + } + + EXPECT_EQ(graph_info->output_operands.size(), 1u); + auto output_operand_id = graph_info->output_operands[0]; + auto output_operand_iter = + graph_info->id_to_operand_map.find(output_operand_id); + ASSERT_TRUE(output_operand_iter != graph_info->id_to_operand_map.end()); + EXPECT_EQ(output_operand_iter->value->data_type, + expected_operand.data_type); + EXPECT_EQ(output_operand_iter->value->dimensions, + expected_operand.dimensions); + } +}; + +TEST_P(MLGraphTestMojo, InstanceNormalizationTest) { + V8TestingScope scope; + // Bind fake WebNN Context in the service for testing. + ScopedWebNNServiceBinder scoped_setup_binder(*this, scope); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + webnn::features::kWebMachineLearningNeuralNetwork); + auto* options = MLContextOptions::Create(); + // Create WebNN Context with GPU device type. + options->setDeviceType(V8MLDeviceType::Enum::kGpu); + auto* builder = CreateGraphBuilder(scope, options); + ASSERT_NE(builder, nullptr); + { + // Test instanceNormalization with default options. + InstanceNormalizationTester{ + .input = {.data_type = V8MLOperandDataType::Enum::kFloat32, + .dimensions = {1, 3, 5, 5}}, + .expected_operand = {.data_type = + blink_mojom::Operand::DataType::kFloat32, + .dimensions = {1, 3, 5, 5}}, + .expected_attributes = + {.scale = absl::nullopt, + .bias = absl::nullopt, + .epsilon = 1e-5, + .layout = blink_mojom::InputOperandLayout::kChannelsFirst}} + .Test(*this, scope, builder); + } + { + // Test instanceNormalization with layout = nhwc. + InstanceNormalizationTester{ + .input = {.data_type = V8MLOperandDataType::Enum::kFloat32, + .dimensions = {1, 3, 4, 5}}, + .options = {.layout = V8MLInputOperandLayout::Enum::kNhwc}, + .expected_operand = {.data_type = + blink_mojom::Operand::DataType::kFloat32, + .dimensions = {1, 3, 4, 5}}, + .expected_attributes = + {.scale = absl::nullopt, + .bias = absl::nullopt, + .epsilon = 1e-5, + .layout = blink_mojom::InputOperandLayout::kChannelsLast}} + .Test(*this, scope, builder); + } + { + // Test instanceNormalization with epsilon = 0.01. + InstanceNormalizationTester{ + .input = {.data_type = V8MLOperandDataType::Enum::kFloat32, + .dimensions = {1, 3, 4, 5}}, + .options = {.epsilon = 0.01}, + .expected_operand = {.data_type = + blink_mojom::Operand::DataType::kFloat32, + .dimensions = {1, 3, 4, 5}}, + .expected_attributes = + {.scale = absl::nullopt, + .bias = absl::nullopt, + .epsilon = 0.01, + .layout = blink_mojom::InputOperandLayout::kChannelsFirst}} + .Test(*this, scope, builder); + } + { + // Test instanceNormalization with scale and bias. + InstanceNormalizationTester{ + .input = {.data_type = V8MLOperandDataType::Enum::kFloat32, + .dimensions = {1, 3, 5, 5}}, + .options = {.scale = + OperandInfoBlink{ + .data_type = V8MLOperandDataType::Enum::kFloat32, + .dimensions = {3}}, + .bias = + OperandInfoBlink{ + .data_type = V8MLOperandDataType::Enum::kFloat32, + .dimensions = {3}}}, + .expected_operand = {.data_type = + blink_mojom::Operand::DataType::kFloat32, + .dimensions = {1, 3, 5, 5}}, + .expected_attributes = + {.scale = + OperandInfoMojo{ + .data_type = blink_mojom::Operand::DataType::kFloat32, + .dimensions = {3}}, + .bias = + OperandInfoMojo{ + .data_type = blink_mojom::Operand::DataType::kFloat32, + .dimensions = {3}}, + .epsilon = 1e-5, + .layout = blink_mojom::InputOperandLayout::kChannelsFirst}} + .Test(*this, scope, builder); + } +} + struct LayerNormalizationTester { OperandInfoBlink input; struct LayerNormalizationOptions {
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc index a489d10..2b839d8 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_elu_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_gather_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_gemm_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_instance_normalization_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_layer_normalization_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_leaky_relu_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pad_options.h" @@ -664,6 +665,35 @@ std::move(layer_normalization_mojo)); } +base::expected<OperationPtr, String> CreateInstanceNormalizationOperation( + const OperandToIdMap& operand_to_id_map, + const MLOperator* instance_normalization) { + auto instance_normalization_mojo = + webnn::mojom::blink::InstanceNormalization::New(); + instance_normalization_mojo->input_operand_id = + GetOperatorInputId(instance_normalization, operand_to_id_map, 0); + instance_normalization_mojo->output_operand_id = + GetOperatorOutputId(instance_normalization, operand_to_id_map); + + const auto* options = static_cast<const MLInstanceNormalizationOptions*>( + instance_normalization->Options()); + CHECK(options); + if (options->hasScale()) { + instance_normalization_mojo->scale_operand_id = + operand_to_id_map.at(options->scale()); + } + if (options->hasBias()) { + instance_normalization_mojo->bias_operand_id = + operand_to_id_map.at(options->bias()); + } + instance_normalization_mojo->layout = + BlinkInputOperandLayoutToMojo(options->layout().AsEnum()); + instance_normalization_mojo->epsilon = options->epsilon(); + + return webnn::mojom::blink::Operation::NewInstanceNormalization( + std::move(instance_normalization_mojo)); +} + OperationPtr CreateMatmulOperation(const OperandToIdMap& operand_to_id_map, const MLOperator* matmul) { auto matmul_mojo = blink_mojom::Matmul::New(); @@ -1081,6 +1111,8 @@ return CreateGatherOperation(operand_to_id_map, op); case MLOperator::OperatorKind::kGemm: return CreateGemmOperation(operand_to_id_map, op); + case MLOperator::OperatorKind::kInstanceNormalization: + return CreateInstanceNormalizationOperation(operand_to_id_map, op); case MLOperator::OperatorKind::kLayerNormalization: return CreateLayerNormalizationOperation(operand_to_id_map, op); case MLOperator::OperatorKind::kLeakyRelu:
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc index 5f1f954..6a0f986 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc
@@ -136,8 +136,8 @@ } if (RuntimeEnabledFeatures::RTCEncodedVideoFrameAdditionalMetadataEnabled()) { - if (delegate_->CaptureTimeIdentifier()) { - metadata->setCaptureTimestamp(delegate_->CaptureTimeIdentifier()->us()); + if (delegate_->PresentationTimestamp()) { + metadata->setTimestamp(delegate_->PresentationTimestamp()->us()); } }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc index a668b73..9fae5e3 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc
@@ -46,7 +46,7 @@ } absl::optional<webrtc::Timestamp> -RTCEncodedVideoFrameDelegate::CaptureTimeIdentifier() const { +RTCEncodedVideoFrameDelegate::PresentationTimestamp() const { base::AutoLock lock(lock_); return webrtc_frame_ ? webrtc_frame_->GetCaptureTimeIdentifier() : absl::nullopt;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h index 09617c4..544b7f4 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h
@@ -34,7 +34,7 @@ String Type() const; uint32_t RtpTimestamp() const; void SetRtpTimestamp(uint32_t timestamp, ExceptionState& exception_state); - absl::optional<webrtc::Timestamp> CaptureTimeIdentifier() const; + absl::optional<webrtc::Timestamp> PresentationTimestamp() const; DOMArrayBuffer* CreateDataBuffer() const; void SetData(const DOMArrayBuffer* data); absl::optional<uint8_t> PayloadType() const;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl index 3a4bb395..746a9d4 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl
@@ -34,7 +34,7 @@ octet payloadType; DOMString mimeType; [RuntimeEnabled=RTCEncodedVideoFrameAdditionalMetadata] - long long captureTimestamp; // microseconds. + long long timestamp; // Presentation timestamp, microseconds. [RuntimeEnabled=RTCEncodedFrameSetMetadata] - unsigned long rtpTimestamp; // microseconds. + unsigned long rtpTimestamp; };
diff --git a/third_party/blink/renderer/modules/printing/web_printer_attributes.idl b/third_party/blink/renderer/modules/printing/web_printer_attributes.idl index 5b62493..b800d35 100644 --- a/third_party/blink/renderer/modules/printing/web_printer_attributes.idl +++ b/third_party/blink/renderer/modules/printing/web_printer_attributes.idl
@@ -21,6 +21,7 @@ unsigned long copies; WebPrintingMultipleDocumentHandling multipleDocumentHandling; + WebPrintColorMode printColorMode; WebPrintQuality printQuality; WebPrintingSides sides; }; @@ -37,6 +38,9 @@ WebPrintingMultipleDocumentHandling multipleDocumentHandlingDefault; sequence<WebPrintingMultipleDocumentHandling> multipleDocumentHandlingSupported; + WebPrintColorMode printColorModeDefault; + sequence<WebPrintColorMode> printColorModeSupported; + WebPrintQuality printQualityDefault; sequence<WebPrintQuality> printQualitySupported;
diff --git a/third_party/blink/renderer/modules/printing/web_printing_enums.idl b/third_party/blink/renderer/modules/printing/web_printing_enums.idl index 2cf3097..2378662 100644 --- a/third_party/blink/renderer/modules/printing/web_printing_enums.idl +++ b/third_party/blink/renderer/modules/printing/web_printing_enums.idl
@@ -34,3 +34,8 @@ "normal", "high", }; + +enum WebPrintColorMode { + "color", + "monochrome", +};
diff --git a/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc b/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc index faca37c3..e1da858 100644 --- a/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc +++ b/third_party/blink/renderer/modules/printing/web_printing_type_converters.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/printing/web_printing_type_converters.h" #include "third_party/blink/public/mojom/printing/web_printing.mojom-blink.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_web_print_color_mode.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_print_job_template_attributes.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printer_attributes.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_printing_mime_media_type.h" @@ -25,6 +26,10 @@ // state: using V8JobState = blink::V8WebPrintJobState; using MojomJobState = blink::mojom::blink::WebPrintJobState; + +// print-color-mode: +using V8ColorMode = blink::V8WebPrintColorMode; +using MojomColorMode = blink::mojom::blink::WebPrintColorMode; } // namespace namespace mojo { @@ -89,6 +94,30 @@ } }; +template <> +struct TypeConverter<V8ColorMode, MojomColorMode> { + static V8ColorMode Convert(const MojomColorMode& color_mode) { + switch (color_mode) { + case MojomColorMode::kColor: + return V8ColorMode(V8ColorMode::Enum::kColor); + case MojomColorMode::kMonochrome: + return V8ColorMode(V8ColorMode::Enum::kMonochrome); + } + } +}; + +template <> +struct TypeConverter<MojomColorMode, V8ColorMode> { + static MojomColorMode Convert(const V8ColorMode& color_mode) { + switch (color_mode.AsEnum()) { + case V8ColorMode::Enum::kColor: + return MojomColorMode::kColor; + case V8ColorMode::Enum::kMonochrome: + return MojomColorMode::kMonochrome; + } + } +}; + } // namespace mojo namespace blink { @@ -124,14 +153,14 @@ new_attributes.multiple_document_handling_supported)); } -void ProcessMultipleDocumentHandling( - const blink::WebPrintJobTemplateAttributes& pjt_attributes, - mojom::blink::WebPrintJobTemplateAttributes* attributes) { - if (pjt_attributes.hasMultipleDocumentHandling()) { - attributes->multiple_document_handling = - mojo::ConvertTo<MojomMultipleDocumentHandling>( - pjt_attributes.multipleDocumentHandling()); - } +void ProcessPrintColorMode( + const mojom::blink::WebPrinterAttributes& new_attributes, + WebPrinterAttributes* current_attributes) { + current_attributes->setPrintColorModeDefault( + mojo::ConvertTo<V8ColorMode>(new_attributes.print_color_mode_default)); + current_attributes->setPrintColorModeSupported( + mojo::ConvertTo<Vector<V8ColorMode>>( + new_attributes.print_color_mode_supported)); } void ProcessSides(const mojom::blink::WebPrinterAttributes& new_attributes, @@ -146,13 +175,6 @@ } } -void ProcessSides(const blink::WebPrintJobTemplateAttributes& pjt_attributes, - mojom::blink::WebPrintJobTemplateAttributes* attributes) { - if (pjt_attributes.hasSides()) { - attributes->sides = mojo::ConvertTo<MojomSides>(pjt_attributes.sides()); - } -} - } // namespace } // namespace blink @@ -169,6 +191,7 @@ blink::ProcessCopies(*printer_attributes, attributes); blink::ProcessDocumentFormat(*printer_attributes, attributes); blink::ProcessMultipleDocumentHandling(*printer_attributes, attributes); + blink::ProcessPrintColorMode(*printer_attributes, attributes); blink::ProcessSides(*printer_attributes, attributes); return attributes; @@ -181,8 +204,18 @@ auto attributes = blink::mojom::blink::WebPrintJobTemplateAttributes::New(); attributes->copies = pjt_attributes->getCopiesOr(1); - blink::ProcessMultipleDocumentHandling(*pjt_attributes, attributes.get()); - blink::ProcessSides(*pjt_attributes, attributes.get()); + if (pjt_attributes->hasMultipleDocumentHandling()) { + attributes->multiple_document_handling = + mojo::ConvertTo<MojomMultipleDocumentHandling>( + pjt_attributes->multipleDocumentHandling()); + } + if (pjt_attributes->hasPrintColorMode()) { + attributes->print_color_mode = + mojo::ConvertTo<MojomColorMode>(pjt_attributes->printColorMode()); + } + if (pjt_attributes->hasSides()) { + attributes->sides = mojo::ConvertTo<MojomSides>(pjt_attributes->sides()); + } return attributes; }
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_router_type_converter.cc b/third_party/blink/renderer/modules/service_worker/service_worker_router_type_converter.cc index 374229e..5b911b44 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_router_type_converter.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_router_type_converter.cc
@@ -52,9 +52,6 @@ return false; } -// TODO(crbug.com/1371756): Make URLPattern has a method to construct the -// SafeURLPattern and remove the conversion from here. -// The method should take a exception_state to raise on regex usage. absl::optional<SafeUrlPattern> RouterUrlPatternConditionToBlink( v8::Isolate* isolate, const V8URLPatternCompatible* url_pattern_compatible, @@ -82,9 +79,6 @@ CHECK(exception_state.HadException()); return absl::nullopt; } - // TODO(crbug.com/1371756): support URLPatternOptions. - // Currently, URLPatternOptions are not included in URLPatternInit, - // and we do not pass the option to the browser side. return safe_url_pattern; }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index 53c8e24a..6422e08 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -480,11 +480,13 @@ shared_image_usage_flags = shared_image_usage_flags | gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION | - gpu::SHARED_IMAGE_USAGE_GLES2 | + gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT; } else { shared_image_usage_flags = shared_image_usage_flags | - gpu::SHARED_IMAGE_USAGE_GLES2 | + gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT; } @@ -1214,7 +1216,8 @@ return; uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | - gpu::SHARED_IMAGE_USAGE_GLES2 | + gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT | gpu::SHARED_IMAGE_USAGE_SCANOUT;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index 05a83dd9b..cbc474a 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -1902,7 +1902,8 @@ GLenum texture_target = GL_TEXTURE_2D; GLuint texture_id = 0; std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; - uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2 | + uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ; if (initial_gpu_ == gl::GpuPreference::kHighPerformance) @@ -1978,13 +1979,21 @@ color_buffer_format_), buffer_usage, gpu::kNullSurfaceHandle, nullptr); if (gpu_memory_buffer) { -#if BUILDFLAG(IS_MAC) - gpu_memory_buffer->SetColorSpace(color_space_); -#endif auto client_shared_image = sii->CreateSharedImage( color_buffer_format_, size, color_space_, origin, back_buffer_alpha_type, usage | additional_usage_flags, "WebGLDrawingBuffer", gpu_memory_buffer->CloneHandle()); +#if BUILDFLAG(IS_MAC) + // Ensure that the backing IOSurface has its color space set to be the + // same as that of the just-created SharedImage (the former is used by + // CoreAnimation, while the latter is used by viz). + // TODO(crbug.com/924198): Explore moving to a CreateSharedImage() + // codepath that sets the color space of the IOSurface on the service + // side and eliminating the usage of GMB here altogether. Will require + // resolving issues with low-latency canvas tests that caused prior + // attempts to be reverted (crbug.com/1346737). + gpu_memory_buffer->SetColorSpace(color_space_); +#endif CHECK(client_shared_image); back_buffer_mailbox = client_shared_image->mailbox(); #if BUILDFLAG(IS_MAC)
diff --git a/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc index bac4c88..4089d434 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
@@ -492,7 +492,8 @@ drawing_buffer_->client()); auto* sii = drawing_buffer_->ContextProvider()->SharedImageInterface(); uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | - gpu::SHARED_IMAGE_USAGE_GLES2 | + gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT; auto client_shared_image = sii->CreateSharedImage( alpha_ ? viz::SinglePlaneFormat::kRGBA_8888
diff --git a/third_party/blink/renderer/platform/graphics/image_to_buffer_copier.cc b/third_party/blink/renderer/platform/graphics/image_to_buffer_copier.cc index 488dcbf8..3414f9d 100644 --- a/third_party/blink/renderer/platform/graphics/image_to_buffer_copier.cc +++ b/third_party/blink/renderer/platform/graphics/image_to_buffer_copier.cc
@@ -38,8 +38,10 @@ dest_shared_image_ = sii_->CreateSharedImage( viz::SinglePlaneFormat::kRGBA_8888, size, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, - gpu::SHARED_IMAGE_USAGE_GLES2, "ImageToBufferCopier", - gpu::kNullSurfaceHandle, gfx::BufferUsage::SCANOUT); + gpu::SHARED_IMAGE_USAGE_GLES2_READ | + gpu::SHARED_IMAGE_USAGE_GLES2_WRITE, + "ImageToBufferCopier", gpu::kNullSurfaceHandle, + gfx::BufferUsage::SCANOUT); CHECK(dest_shared_image_); gl_->WaitSyncTokenCHROMIUM(sii_->GenUnverifiedSyncToken().GetConstData()); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index ae5be8dd..d961671 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -1075,7 +1075,7 @@ TRACE_ID_WITH_SCOPE("BlinkResourceID", TRACE_ID_LOCAL(identifier)), "url", resource_request.Url()); base::ScopedClosureRunner timer(base::BindOnce( - [](base::TimeTicks start, bool is_data) { + [](base::TimeTicks start, bool is_data, bool is_preload_request) { base::TimeDelta elapsed = base::TimeTicks::Now() - start; base::UmaHistogramMicrosecondsTimes("Blink.Fetch.RequestResourceTime2", elapsed); @@ -1083,8 +1083,13 @@ base::UmaHistogramMicrosecondsTimes( "Blink.Fetch.RequestResourceTime2.Data", elapsed); } + if (is_preload_request) { + base::UmaHistogramMicrosecondsTimes( + "Blink.Fetch.RequestResourceTime2.Preload", elapsed); + } }, - base::TimeTicks::Now(), params.Url().ProtocolIsData())); + base::TimeTicks::Now(), params.Url().ProtocolIsData(), + params.IsSpeculativePreload() || params.IsLinkPreload())); TRACE_EVENT1("blink,blink.resource", "ResourceFetcher::requestResource", "url", params.Url().ElidedString().Utf8());
diff --git a/third_party/blink/renderer/platform/media/BUILD.gn b/third_party/blink/renderer/platform/media/BUILD.gn index 7062313..5204e7c 100644 --- a/third_party/blink/renderer/platform/media/BUILD.gn +++ b/third_party/blink/renderer/platform/media/BUILD.gn
@@ -104,8 +104,8 @@ if (enable_hls_demuxer) { sources += [ - "hls_data_source_provider_impl.cc", - "hls_data_source_provider_impl.h", + "multi_buffer_data_source_factory.cc", + "multi_buffer_data_source_factory.h", ] } } @@ -149,10 +149,6 @@ "//third_party/blink/renderer/platform:test_support", ] - if (enable_hls_demuxer) { - sources += [ "hls_data_source_provider_impl_unittest.cc" ] - } - if (media_use_ffmpeg || !is_android) { sources += [ "buffered_data_source_host_impl_unittest.cc",
diff --git a/third_party/blink/renderer/platform/media/hls_data_source_provider_impl.h b/third_party/blink/renderer/platform/media/hls_data_source_provider_impl.h deleted file mode 100644 index 9412c1b..0000000 --- a/third_party/blink/renderer/platform/media/hls_data_source_provider_impl.h +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_HLS_DATA_SOURCE_PROVIDER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_HLS_DATA_SOURCE_PROVIDER_IMPL_H_ - -#include <deque> -#include <memory> -#include "base/memory/raw_ptr.h" -#include "base/memory/scoped_refptr.h" -#include "base/task/single_thread_task_runner.h" -#include "base/time/tick_clock.h" -#include "base/types/pass_key.h" -#include "media/base/data_source.h" -#include "media/base/media_log.h" -#include "media/filters/hls_data_source_provider.h" -#include "third_party/blink/public/platform/media/url_index.h" -#include "third_party/blink/renderer/platform/platform_export.h" - -namespace blink { - -class BufferedDataSourceHostImpl; - -class PLATFORM_EXPORT HlsDataSourceProviderImpl - : public media::HlsDataSourceProvider { - public: - // An instance of DataSourceFactory allows separation of DataSource creation - // and DataSourceStream buffer management for easier testing. - class DataSourceFactory { - public: - using DataSourceCb = - base::OnceCallback<void(std::unique_ptr<media::DataSource>)>; - virtual ~DataSourceFactory() = 0; - virtual void CreateDataSource(GURL uri, DataSourceCb cb) = 0; - }; - - ~HlsDataSourceProviderImpl() override; - explicit HlsDataSourceProviderImpl( - std::unique_ptr<DataSourceFactory> factory); - - // media::HlsDataSourceProvider implementation - void ReadFromUrl(GURL uri, - absl::optional<media::hls::types::ByteRange> range, - ReadCb callback) override; - void ReadFromExistingStream( - std::unique_ptr<media::HlsDataSourceStream> stream, - ReadCb callback) override; - void AbortPendingReads(base::OnceClosure cb) override; - - private: - void OnDataSourceReady(absl::optional<media::hls::types::ByteRange> range, - ReadCb callback, - std::unique_ptr<media::DataSource> data_source); - void OnStreamReleased(media::HlsDataSourceStream::StreamId stream_id); - void DataSourceInitialized(media::HlsDataSourceStream::StreamId stream_id, - absl::optional<media::hls::types::ByteRange> range, - ReadCb callback, - bool success); - - std::unique_ptr<DataSourceFactory> data_source_factory_; - - media::HlsDataSourceStream::StreamId::Generator stream_id_generator_; - - base::flat_map<media::HlsDataSourceStream::StreamId, - std::unique_ptr<media::DataSource>> - data_source_map_; - - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory<HlsDataSourceProviderImpl> weak_factory_{this}; -}; - -class PLATFORM_EXPORT MultiBufferDataSourceFactory - : public HlsDataSourceProviderImpl::DataSourceFactory { - public: - using UrlDataCb = base::RepeatingCallback< - void(const GURL& url, base::OnceCallback<void(scoped_refptr<UrlData>)>)>; - - ~MultiBufferDataSourceFactory() override; - MultiBufferDataSourceFactory( - media::MediaLog* media_log, - UrlDataCb get_url_data, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - const base::TickClock* tick_clock); - - void CreateDataSource(GURL uri, DataSourceCb cb) override; - - private: - void OnUrlData(DataSourceCb cb, - base::RepeatingCallback<void(bool)> download_cb, - scoped_refptr<UrlData> data); - - std::unique_ptr<media::MediaLog> media_log_; - UrlDataCb get_url_data_; - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; - - std::unique_ptr<BufferedDataSourceHostImpl> buffered_data_source_host_; - base::WeakPtrFactory<MultiBufferDataSourceFactory> weak_factory_{this}; -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.cc new file mode 100644 index 0000000..b8b8e01 --- /dev/null +++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.cc
@@ -0,0 +1,60 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.h" + +#include "base/logging.h" +#include "base/ranges/algorithm.h" +#include "base/task/bind_post_task.h" +#include "base/types/pass_key.h" +#include "media/formats/hls/types.h" +#include "third_party/blink/renderer/platform/media/buffered_data_source_host_impl.h" +#include "third_party/blink/renderer/platform/media/multi_buffer_data_source.h" + +namespace blink { + +MultiBufferDataSourceFactory::~MultiBufferDataSourceFactory() = default; + +MultiBufferDataSourceFactory::MultiBufferDataSourceFactory( + media::MediaLog* media_log, + UrlDataCb get_url_data, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + const base::TickClock* tick_clock) + : media_log_(media_log->Clone()), + get_url_data_(get_url_data), + main_task_runner_(std::move(main_task_runner)) { + buffered_data_source_host_ = std::make_unique<BufferedDataSourceHostImpl>( + base::DoNothing(), tick_clock); +} + +void MultiBufferDataSourceFactory::CreateDataSource(GURL uri, DataSourceCb cb) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + auto download_cb = +#if DCHECK_IS_ON() + base::BindRepeating( + [](const std::string url, bool is_downloading) { + DVLOG(1) << __func__ << "(" << url << ", " << is_downloading << ")"; + }, + uri.spec()); +#else + base::DoNothing(); +#endif + + get_url_data_.Run(std::move(uri), + base::BindOnce(&MultiBufferDataSourceFactory::OnUrlData, + weak_factory_.GetWeakPtr(), std::move(cb), + std::move(download_cb))); +} + +void MultiBufferDataSourceFactory::OnUrlData( + DataSourceCb cb, + base::RepeatingCallback<void(bool)> download_cb, + scoped_refptr<UrlData> data) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + std::move(cb).Run(std::make_unique<MultiBufferDataSource>( + main_task_runner_, std::move(data), media_log_.get(), + buffered_data_source_host_.get(), std::move(download_cb))); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.h b/third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.h new file mode 100644 index 0000000..faac8b07 --- /dev/null +++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.h
@@ -0,0 +1,55 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_MULTI_BUFFER_DATA_SOURCE_FACTORY_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_MULTI_BUFFER_DATA_SOURCE_FACTORY_H_ + +#include <memory> +#include "base/memory/raw_ptr.h" +#include "base/memory/scoped_refptr.h" +#include "base/task/single_thread_task_runner.h" +#include "base/time/tick_clock.h" +#include "base/types/pass_key.h" +#include "media/base/data_source.h" +#include "media/base/media_log.h" +#include "media/filters/hls_data_source_provider_impl.h" +#include "third_party/blink/public/platform/media/url_index.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +class BufferedDataSourceHostImpl; + +class PLATFORM_EXPORT MultiBufferDataSourceFactory + : public media::HlsDataSourceProviderImpl::DataSourceFactory { + public: + using UrlDataCb = base::RepeatingCallback< + void(const GURL& url, base::OnceCallback<void(scoped_refptr<UrlData>)>)>; + + ~MultiBufferDataSourceFactory() override; + MultiBufferDataSourceFactory( + media::MediaLog* media_log, + UrlDataCb get_url_data, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + const base::TickClock* tick_clock); + + void CreateDataSource(GURL uri, DataSourceCb cb) override; + + private: + void OnUrlData(DataSourceCb cb, + base::RepeatingCallback<void(bool)> download_cb, + scoped_refptr<UrlData> data); + + std::unique_ptr<media::MediaLog> media_log_; + UrlDataCb get_url_data_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + + std::unique_ptr<BufferedDataSourceHostImpl> buffered_data_source_host_; + base::WeakPtrFactory<MultiBufferDataSourceFactory> weak_factory_{this}; +}; + +} // namespace blink + +#endif // ifndef + // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_MULTI_BUFFER_DATA_SOURCE_FACTORY_H_
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index 5fd973bc..d1f180d 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -95,7 +95,8 @@ #include "ui/gfx/geometry/size.h" #if BUILDFLAG(ENABLE_HLS_DEMUXER) -#include "third_party/blink/renderer/platform/media/hls_data_source_provider_impl.h" +#include "media/filters/hls_data_source_provider_impl.h" +#include "third_party/blink/renderer/platform/media/multi_buffer_data_source_factory.h" #endif // BUILDFLAG(ENABLE_HLS_DEMUXER) #if BUILDFLAG(IS_ANDROID) @@ -1585,7 +1586,7 @@ base::SequenceBound<media::HlsDataSourceProvider> WebMediaPlayerImpl::GetHlsDataSourceProvider() { DCHECK(main_task_runner_->BelongsToCurrentThread()); - return base::SequenceBound<HlsDataSourceProviderImpl>( + return base::SequenceBound<media::HlsDataSourceProviderImpl>( main_task_runner_, std::make_unique<MultiBufferDataSourceFactory>( media_log_.get(),
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc index 0610fba..02affbaf 100644 --- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc +++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -540,8 +540,9 @@ std::vector<gfx::BufferPlane> planes; uint32_t usage = - gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_RASTER | - gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT; + gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_GLES2_WRITE | + gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | + gpu::SHARED_IMAGE_USAGE_SCANOUT; #if BUILDFLAG(IS_APPLE) usage |= gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX; #endif
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc index cf705b2..d8ebce0 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -2466,7 +2466,7 @@ } #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \ - defined(MEMORY_SANITIZER) + defined(MEMORY_SANITIZER) || defined(UNDEFINED_SANITIZER) // Flaky under sanitizers and in other "slow" bot configs: // https://crbug.com/1029250 #define MAYBE_VSyncAlignedGestureScrollPinchScroll \
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index ee75008..4c3d992 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1536,14 +1536,11 @@ # See https://docs.google.com/document/d/1FH0iG8G8mEebjMpVA_zvSfHBWUhWqC92jRFctaGcxrc/edit#heading=h.pacsgp238vkn crbug.com/1488371 virtual/deprecate-unload/http/tests/history/history-replace-updates-current-item.html [ Failure Skip Timeout ] -crbug.com/1488371 virtual/deprecate-unload/http/tests/navigation/image-load-in-subframe-unload-handler.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/http/tests/navigation/image-load-in-unload-handler.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/browsers/browsing-the-web/back-forward-cache/events.html [ Failure Skip Timeout ] -crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/browsers/browsing-the-web/unloading-documents/001.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/browsers/browsing-the-web/unloading-documents/unload/009.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html [ Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/browsers/the-window-object/open-close/close_unload.html [ Failure Skip Timeout ] -crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/browsers/the-window-object/self-et-al.window.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/webappapis/scripting/events/event-handler-attributes-body-window.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/webappapis/scripting/events/event-handler-attributes-frameset-window.html [ Failure Skip Timeout ] crbug.com/1488371 virtual/deprecate-unload/external/wpt/html/webappapis/scripting/events/event-handler-attributes-windowless-body.html [ Failure Skip Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index b6aa743..e86e8924 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1822,6 +1822,7 @@ ], "exclusive_tests": "ALL", "args": ["--enable-features=NoForcedFrameUpdatesForWebTests", + "--disable-features=KeepAliveInBrowserMigration", "--disable-threaded-compositing", "--disable-threaded-animation"], "expires": "Dec 1, 2024" }, @@ -2016,7 +2017,8 @@ ], "exclusive_tests": "ALL", "args": [ - "--enable-features=Prerender2InNewTab,Prerender2AllowActivationInBackground" + "--enable-features=Prerender2InNewTab,Prerender2AllowActivationInBackground", + "--disable-features=KeepAliveInBrowserMigration" ], "owners": ["nhiroki@chromium.org"], "expires": "Jul 1, 2024" @@ -2274,7 +2276,7 @@ "--disable-features=DeprecateUnload", "--disable-threaded-compositing", "--disable-threaded-animation" ], - "expires": "Dec 1, 2023" + "expires": "Apr 1, 2024" }, { "prefix": "clone-for-branch2-disabled", @@ -2565,7 +2567,6 @@ "http/tests/inspector-protocol/permissions-policy.js", "http/tests/navigation/history-back-across-form-submission-to-fragment.html", "http/tests/navigation/image-css-load-in-subframe-unload-handler.html", - "http/tests/navigation/image-load-in-subframe-unload-handler.html", "http/tests/navigation/image-load-in-unload-handler.html", "http/tests/navigation/redirect-on-back-updates-history-item.html", "http/tests/navigation/redirect-on-reload-updates-history-item.html", @@ -2595,7 +2596,6 @@ "external/wpt/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html", "external/wpt/html/browsers/the-window-object/BarProp.window.js", "external/wpt/html/browsers/the-window-object/open-close/close_unload.html", - "external/wpt/html/browsers/the-window-object/self-et-al.window.js", "external/wpt/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js", "external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js", "external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-xml.window.js",
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 111bf9df0..a1475e0 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -2471,6 +2471,13 @@ ] ], "crashtests": { + "add-list-item-marker.html": [ + "fa14315cabfdba936e5c81c53d9a0b2583a3cfe1", + [ + null, + {} + ] + ], "as-baseline-aligned-grid-item.html": [ "f9a9e1dad0d21f9b29c8643a57d9862582a4a1d0", [ @@ -4075,6 +4082,15 @@ ] }, "overflow-wrap": { + "crashtests": { + "overflow-wrap-leading-floats-crash.html": [ + "0661cf7286494ca00c91e60b635c25501b3a8d87", + [ + null, + {} + ] + ] + }, "overflow-wrap-break-word-long-crash.html": [ "e318386ded5bd3d1d61cf876fe420c8f5ada799f", [ @@ -139846,7 +139862,7 @@ ] ], "masonry-item-placement-001.html": [ - "2f8cfbfacc21aade2e06f858f83abb0af468d7bf", + "649e1edb7cb9bd903f795f6e605d12ae566390eb", [ null, [ @@ -139859,7 +139875,7 @@ ] ], "masonry-item-placement-002.html": [ - "5f7083b173331f1e4593d4d97cc0513039606316", + "7d321bf731684173f483d6ba3abde11da307de8e", [ null, [ @@ -139872,7 +139888,7 @@ ] ], "masonry-item-placement-003.html": [ - "4d490c18d5d1d79f960e82ded542e1de5bccadc6", + "8a183cffc6bd3f59fb0c7ca58b9a85588bdab3f8", [ null, [ @@ -140058,7 +140074,7 @@ ] ], "masonry-order-002.html": [ - "ae68f4e631a2f44540a60a7eebb5ef9a3ac9b84a", + "abad3d44b8326535bb1f44832011a1a6145a47b9", [ null, [ @@ -140114,7 +140130,7 @@ ] ], "masonry-track-sizing-explicit-block.html": [ - "05f60893900f44753d4873e60d4b348bd6270a07", + "3cc98708fe9aec94293eb5bcb296f01d3a4a7508", [ null, [ @@ -140153,7 +140169,7 @@ ] ], "masonry-track-sizing-span-row.html": [ - "6058ca5e7441c87db5f29cdb37d09e55134ead82", + "475c27f1ebea5598c6e3fcec0e21d13b08bc9499", [ null, [ @@ -320379,7 +320395,7 @@ [] ], "masonry-item-placement-001-ref.html": [ - "7108a11a100e58ac89daec02c1e874f0c6c5ab95", + "2e100c3be619cbbb55ea430edb92d08dd2af4b2a", [] ], "masonry-item-placement-002-ref.html": [ @@ -320439,11 +320455,11 @@ }, "order": { "masonry-order-001-ref.html": [ - "371699981544487f6b7c6b1e8d084e746057a07d", + "6f20bd05838efed10a0915b30941ff7bcbb73b6a", [] ], "masonry-order-002-ref.html": [ - "5dd4e47d80b7777ab3e2473d33178cc00bb4cae8", + "15be3fde83710c6a7876a5befa8d91dc9f26f8e7", [] ] }, @@ -387021,6 +387037,10 @@ "1b63235b7cdffe9ebb43bfac3a01d5220e1519fb", [] ], + "register-service-worker-iframe.https.html": [ + "547ab1d93d9adb9cb82ea797ee5e900b9d0e067c", + [] + ], "report.py": [ "7d0fa36019ef58c8c7764767f267628cd05bc285", [] @@ -387046,7 +387066,7 @@ [] ], "shared-storage-writable-fetch-request-fallback-to-network-iframe.https.html": [ - "8229ce88d82ad05e8f7e1d1e9886f49c282bc805", + "3451d91477ddc7b417a207a1d7afcf2384e83e7a", [] ], "shared-storage-writable-fetch-request-fallback-to-network-worker.js": [ @@ -387090,11 +387110,11 @@ [] ], "util.js": [ - "f82765846c22a452f29cc6cd097080955499d1f8", + "4a7fcc4590ff53e41695e9a6c11304e287eb3384", [] ], "util.sub.js": [ - "970c33b7f2551e76c57d5cc2431b3131084fd025", + "f147209d6096375d9a5ccc5b1dc42a36d3be6bec", [] ], "verify-get-undefined-module.js": [ @@ -436080,6 +436100,344 @@ } }, "css-align": { + "abspos": { + "align-self-htb-ltr-htb.html": [ + "786cec7acf76607a92b44a76880c1a2543da25e4", + [ + null, + {} + ] + ], + "align-self-htb-ltr-vlr.html": [ + "917e50d5e694b470a034faeabb4cfb0d557c1ed8", + [ + null, + {} + ] + ], + "align-self-htb-ltr-vrl.html": [ + "b60d4615314440e0a1ba563737babfa5e8db69b5", + [ + null, + {} + ] + ], + "align-self-htb-rtl-htb.html": [ + "9bf919dd46522c46a0f563ba215858748271ef08", + [ + null, + {} + ] + ], + "align-self-htb-rtl-vlr.html": [ + "5c1e8c75c935e76466118ed1695d01c54c3271c0", + [ + null, + {} + ] + ], + "align-self-htb-rtl-vrl.html": [ + "b7f0056976893b0e093dbe63b7a7f669abf19162", + [ + null, + {} + ] + ], + "align-self-vlr-ltr-htb.html": [ + "98e3c0b9366591f26502263b8130861966d656d1", + [ + null, + {} + ] + ], + "align-self-vlr-ltr-vlr.html": [ + "73585d2db5a819b2a9be3fb2555ea45bf8546473", + [ + null, + {} + ] + ], + "align-self-vlr-ltr-vrl.html": [ + "39ecd388999cde7b344c8f8832060611580ad7bd", + [ + null, + {} + ] + ], + "align-self-vlr-rtl-htb.html": [ + "7a4167f62a5ac156d3e99985a5c8d3c6dfc36e93", + [ + null, + {} + ] + ], + "align-self-vlr-rtl-vlr.html": [ + "4ce7d46520a171a57ed4068e52d78a8f115e4862", + [ + null, + {} + ] + ], + "align-self-vlr-rtl-vrl.html": [ + "0fe160442f460499385eefb3255a266e5d5f4f36", + [ + null, + {} + ] + ], + "align-self-vrl-ltr-htb.html": [ + "98e6145a6313409cfb55c8b7e3b5c0a573f2231d", + [ + null, + {} + ] + ], + "align-self-vrl-ltr-vlr.html": [ + "d22b347da3044c5e0da34162faa80f74429ac065", + [ + null, + {} + ] + ], + "align-self-vrl-ltr-vrl.html": [ + "602b7afb7b8b32bb8ccd0a3729629643a258be7b", + [ + null, + {} + ] + ], + "align-self-vrl-rtl-htb.html": [ + "1dcfd8709f0b7c17f9762d9e96d1d06bb5eb3fbc", + [ + null, + {} + ] + ], + "align-self-vrl-rtl-vlr.html": [ + "d22b347da3044c5e0da34162faa80f74429ac065", + [ + null, + {} + ] + ], + "align-self-vrl-rtl-vrl.html": [ + "602b7afb7b8b32bb8ccd0a3729629643a258be7b", + [ + null, + {} + ] + ], + "justify-self-htb-ltr-htb.html": [ + "cfef344e041ed1029f4d44ee9bf91745744527d9", + [ + null, + {} + ] + ], + "justify-self-htb-ltr-vlr.html": [ + "55680f4b2c46dad322677eb6d845187855349bd9", + [ + null, + {} + ] + ], + "justify-self-htb-ltr-vrl.html": [ + "57ee3af6408bde8597df863695c4cd6b2456ceb5", + [ + null, + {} + ] + ], + "justify-self-htb-rtl-htb.html": [ + "95e54c2b990b497ef000d2ab3e8a6e3cd3bd88dd", + [ + null, + {} + ] + ], + "justify-self-htb-rtl-vlr.html": [ + "e7224e76db6de9bd49080af30283a57981be48e1", + [ + null, + {} + ] + ], + "justify-self-htb-rtl-vrl.html": [ + "ba7e98a6767831e38a9e5fa67f9d17a37979f0e2", + [ + null, + {} + ] + ], + "justify-self-vlr-ltr-htb.html": [ + "d47c504679b1b543b13957e90059411b4fbaa71c", + [ + null, + {} + ] + ], + "justify-self-vlr-ltr-vlr.html": [ + "71e3687f6f4ac3d35c3f28464aa2c08be31de869", + [ + null, + {} + ] + ], + "justify-self-vlr-ltr-vrl.html": [ + "ae90d4da0d8f2277025bbefdfc2b7e2174001854", + [ + null, + {} + ] + ], + "justify-self-vlr-rtl-htb.html": [ + "1a192b56924c95aeed27efbe1133f6b5f912f683", + [ + null, + {} + ] + ], + "justify-self-vlr-rtl-vlr.html": [ + "cb9986db10159e2f591e0e577a95b01aa78ee3d0", + [ + null, + {} + ] + ], + "justify-self-vlr-rtl-vrl.html": [ + "fb717a051f2a2b4b16f134dae830d8b403af7b46", + [ + null, + {} + ] + ], + "justify-self-vrl-ltr-htb.html": [ + "e2cbff322b3051a5c5c9b87cdab55c6dfaeb4d9f", + [ + null, + {} + ] + ], + "justify-self-vrl-ltr-vlr.html": [ + "5aa2f482888be3ff299ff6291d65728aa0024403", + [ + null, + {} + ] + ], + "justify-self-vrl-ltr-vrl.html": [ + "cf2db8d369bf195d40fd2c5e933297558aa269ca", + [ + null, + {} + ] + ], + "justify-self-vrl-rtl-htb.html": [ + "317e53e92e0a40f3dad0b40194363ed1e9bba326", + [ + null, + {} + ] + ], + "justify-self-vrl-rtl-vlr.html": [ + "2d144d16aa097880b85701b931ef7010319ca0ca", + [ + null, + {} + ] + ], + "justify-self-vrl-rtl-vrl.html": [ + "026c6e96816ffbb56bbb2e9f1275a0dfb2bdbf4f", + [ + null, + {} + ] + ], + "safe-align-self-htb.html": [ + "9e259c1e630ad2184752e66f6db9142686fc4ea3", + [ + null, + {} + ] + ], + "safe-align-self-vlr.html": [ + "d47b1836d52ed2bd8bf300080e09c6382055b286", + [ + null, + {} + ] + ], + "safe-align-self-vrl.html": [ + "3432762007efe52af47712d15362280cfb5e3a13", + [ + null, + {} + ] + ], + "safe-justify-self-htb.html": [ + "0fa5cc34d57347f69665507be6c4fea1a7f98cdb", + [ + null, + {} + ] + ], + "safe-justify-self-vlr.html": [ + "7554975f1be1e1cbb990decb0ded47f53ad0763c", + [ + null, + {} + ] + ], + "safe-justify-self-vrl.html": [ + "fe2405cf798a601c41867c34f002b1f5a6d579e3", + [ + null, + {} + ] + ], + "stretch-intrinsic-size-htb-htb.html": [ + "dc7df332e403d838dea63a0e27bea948771b411b", + [ + null, + {} + ] + ], + "stretch-intrinsic-size-htb-vrl.html": [ + "cd2c9b9abc49764f8eb93ad49abd5fe32e110821", + [ + null, + {} + ] + ], + "stretch-intrinsic-size-vrl-htb.html": [ + "7b1002191f2fef22b0a95b4830cc24db807ab577", + [ + null, + {} + ] + ], + "stretch-intrinsic-size-vrl-vrl.html": [ + "10f11a9f12d36ee042db9d4fdc8134799615750e", + [ + null, + {} + ] + ], + "table-align-self-stretch.html": [ + "bedd0a56950d21ef9e3bd81ffb30fe9534a621ef", + [ + null, + {} + ] + ], + "table-justify-self-stretch.html": [ + "c409b10714095581523df4a4d8305b9d7ac249f7", + [ + null, + {} + ] + ] + }, "animation": { "align-no-interpolation.html": [ "037743bdd32fc8de5c60e0608a08085cd3cd6fe7", @@ -616574,7 +616932,7 @@ ] ], "percent-encoding.html": [ - "696734b663d2cbd49adbb6a2a400d0747be5ebc6", + "1f1794bdae09db3a501479717121d93938e9869a", [ null, { @@ -623708,8 +624066,22 @@ {} ] ], + "shared-storage-writable-service-worker-fetch.tentative.https.sub.html": [ + "ea7af527b540d303cf3e41c7afd8d88071bcd293", + [ + null, + {} + ] + ], + "shared-storage-writable-service-worker-iframe.tentative.https.sub.html": [ + "9eb2820145ea31c250e4a5003c0d5974941d71ca", + [ + null, + {} + ] + ], "shared-storage-writable-service-worker-img.tentative.https.sub.html": [ - "9e7326d3c4d62435ef7a344864341bdd318965fb", + "6d481559ee75e96955cc8f83c464200e4c4a9039", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001-ref.html index 7108a11..2e100c3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001-ref.html
@@ -8,38 +8,38 @@ <title>Reference: Masonry layout using `grid-column/row`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-template-columns: repeat(4,80px); - grid-template-rows: masonry; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-template-columns: repeat(4,80px); + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> <grid> + <item style="grid-column:1">6</item> + <item style="grid-column:2">5</item> + <item style="grid-column:span 2">4</item> <item style="margin-top:10px">3</item> <item style="grid-column:span 2">1</item> <item>2</item> - <item style="grid-column:2">5</item> - <item style="grid-column:span 2">4</item> - <item style="grid-column:1">6</item> </grid> </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html index 2f8cfbf..649e1ed 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html
@@ -10,38 +10,38 @@ <link rel="help" href="https://drafts.csswg.org/css-grid-2"> <link rel="match" href="masonry-item-placement-001-ref.html"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-template-columns: repeat(4,80px); - grid-template-rows: masonry; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-template-columns: repeat(4,80px); + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> <grid> - <item style="grid-column:2/span 2">1</item> - <item>2</item> - <item style="margin-top:10px">3</item> - <item style="grid-column:3/span 2">4</item> + <item style="grid-column:1">6</item> <item>5</item> - <item>6</item> + <item style="margin-top:10px">3</item> + <item style="grid-column:span 2">1</item> + <item>2</item> + <item style="grid-column:3/span 2">4</item> </grid> </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html index 5f7083b..7d321bf7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html
@@ -10,38 +10,38 @@ <link rel="help" href="https://drafts.csswg.org/css-grid-2"> <link rel="match" href="masonry-item-placement-002-ref.html"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-auto-columns: 80px; - grid-template-rows: masonry; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-auto-columns: 80px; + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> <grid> - <item style="grid-column:foo 2; grid-row:span 2">2</item> + <item style="grid-column:1/span 4;">1</item> <item>3</item> + <item style="grid-column:foo 2; grid-row:span 2">2</item> <item style="grid-column:span 3">4</item> <item>5</item> <item>6</item> - <item style="grid-column:span 4; grid-row:-100">1</item> </grid> </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html index 4d490c18..8a183cff 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html
@@ -10,37 +10,37 @@ <link rel="help" href="https://drafts.csswg.org/css-grid-2"> <link rel="match" href="masonry-item-placement-003-ref.html"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-auto-flow: dense; - grid-auto-columns: 80px; - grid-template-rows: masonry; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-auto-flow: dense; + grid-auto-columns: 80px; + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> <grid> <item style="grid-row:-100">1</item> + <item>3</item> <item style="grid-column:foo 2; grid-row:span 2">2</item> <item style="grid-column:span 3">4</item> - <item>3</item> <item>5</item> <item>6</item> </grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001-ref.html index 37169998..6f20bd0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001-ref.html
@@ -8,28 +8,28 @@ <title>Reference: Masonry layout using `order`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-template-columns: repeat(4,auto); - grid-template-rows: masonry; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-template-columns: repeat(4,auto); + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> @@ -38,6 +38,6 @@ <item style="margin-top:10px">4</item> <item>6</item> <item>2</item> + <item style="grid-column: span 2">5</item> <item>3</item> - <item style="grid-column:3/span 2">5</item> </grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002-ref.html index 5dd4e47d..15be3fd 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002-ref.html
@@ -8,36 +8,36 @@ <title>Reference: Masonry layout using `order` and `masonry-auto-flow: next`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-template-columns: repeat(4,auto); - grid-template-rows: masonry; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-template-columns: repeat(4,auto); + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> <grid> - <item>1</item> - <item style="margin-top:10px">4</item> - <item>6</item> - <item>2</item> - <item style="grid-column:1/span 2">5</item> - <item style="grid-column:3">3</item> + <item style="grid-column: 1">1</item> + <item style="margin-top:10px; grid-column: 2;">4</item> + <item style="grid-column: 3">6</item> + <item style="grid-column: 4">2</item> + <item style="grid-column: 2/span 2">5</item> + <item>3</item> </grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html index ae68f4e..abad3d4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html
@@ -10,37 +10,37 @@ <link rel="help" href="https://drafts.csswg.org/css-grid-2"> <link rel="match" href="masonry-order-002-ref.html"> <style> -html,body { - color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; -} + html,body { + color:black; background-color:white; font:25px/1 monospace; padding:0; margin:0; + } -grid { - display: inline-grid; - gap: 10px 20px; - grid-template-columns: repeat(4,auto); - grid-template-rows: masonry; - masonry-auto-flow: next; - color: #444; - border: 1px solid; - padding: 2px; -} + grid { + display: inline-grid; + gap: 10px 20px; + grid-template-columns: repeat(4,auto); + grid-template-rows: masonry; + masonry-auto-flow: next; + color: #444; + border: 1px solid; + padding: 2px; + } -item { - background-color: #444; - color: #fff; - padding: 20px; - margin: 3px; - border: 5px solid blue; -} -</style> + item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + } + </style> </head> <body> <grid> <item>1</item> <item style="order:1">2</item> - <item style="order:2">3</item> + <item style="order:1">3</item> <item style="margin-top:10px">4</item> - <item style="order:1; grid-column:span 2">5</item> + <item style="order:2; grid-column:span 2">5</item> <item>6</item> </grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-explicit-block.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-explicit-block.html index 05f6089..3cc98708 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-explicit-block.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-explicit-block.html
@@ -11,37 +11,35 @@ <body> <style> -grid { - display: grid; - grid-template-columns: auto 1fr; - grid-template-rows: masonry; - width: 300px; - height: 100px; -} + grid { + display: grid; + grid-template-columns: 100px 1fr; + grid-template-rows: masonry; + width: 300px; + height: 100px; + } -box1 { - height: 50px; - width: 30px; - background-color: blue; -} + box1 { + height: 50px; + width: 30px; + background-color: blue; + } -box2 { - height: 50px; - background-color: red; -} + box2 { + height: 50px; + background-color: red; + } -box3 { - height: 50px; - width: 100px; - grid-row: 2; - grid-column: 1; - background-color: purple; -} + box3 { + height: 50px; + width: 100px; + background-color: purple; + } -box4 { - height: 50px; - background-color: green; -} + box4 { + height: 50px; + background-color: green; + } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-span-row.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-span-row.html index 6058ca5..475c27f1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-span-row.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/track-sizing/masonry-track-sizing-span-row.html
@@ -11,46 +11,45 @@ <body> <style> -grid { - display: grid; - grid-template-columns: auto 1fr; - grid-template-rows: masonry; - width: 300px; - height: 100px; -} + grid { + display: grid; + grid-template-columns: 50px 1fr; + grid-template-rows: masonry; + width: 300px; + height: 100px; + } -box1 { - height: 50px; - width: 50px; - background-color: blue; -} + box1 { + height: 50px; + width: 50px; + background-color: blue; + } -box2 { - height: 50px; - background-color: red; -} + box2 { + height: 50px; + background-color: red; + } -box3 { - width: 100px; - height: 50px; - background-color: purple; - z-index: 1; -} + box3 { + width: 100px; + height: 50px; + background-color: purple; + z-index: 1; + } -box4 { - height: 50px; - width: 300px; - grid-column-start: 1; - grid-column-end: 3; - background-color: green; -} + box4 { + height: 50px; + width: 300px; + grid-column: span 2; + background-color: green; + } </style> <grid> <box1>1</box1> <box2>2</box2> - <box3>3</box3> <box4>4</box4> + <box3>3</box3> </grid> </body>
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/permission-geolocation.https.html b/third_party/blink/web_tests/external/wpt/fenced-frame/permission-geolocation.https.html index 98b5a72b..e9ad535 100644 --- a/third_party/blink/web_tests/external/wpt/fenced-frame/permission-geolocation.https.html +++ b/third_party/blink/web_tests/external/wpt/fenced-frame/permission-geolocation.https.html
@@ -35,13 +35,14 @@ win.onload = resolve; }); - const unloadPromise = new Promise(resolve => { - win.onunload = resolve; + // Pagehide can be used to detect the document destruction. + const pagehidePromise = new Promise(resolve => { + win.onpagehide = resolve; }); await win.runTest(fenced_frame_url); win.close(); - await unloadPromise; + await pagehidePromise; } promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/self-et-al.window.js b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/self-et-al.window.js index 1b0fa121..c425228 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/self-et-al.window.js +++ b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/self-et-al.window.js
@@ -28,8 +28,8 @@ async_test(t => { const otherW = window.open(); assert_equals(otherW[windowProxySelfReference], otherW, `${windowProxySelfReference} is broken`); - otherW.onunload = t.step_func(() => { - assert_equals(otherW[windowProxySelfReference], otherW, `${windowProxySelfReference} got cleared after browsing context unload`); + otherW.onpagehide = t.step_func(() => { + assert_equals(otherW[windowProxySelfReference], otherW, `${windowProxySelfReference} got cleared after browsing context pagehide`); t.step_timeout(() => { assert_equals(otherW.opener, null); // Ensure browsing context is discarded assert_equals(otherW[windowProxySelfReference], otherW, `${windowProxySelfReference} got cleared after browsing context removal`);
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/resources/router-rules.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/resources/router-rules.js index 67871a2..f8fe403 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/resources/router-rules.js +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/resources/router-rules.js
@@ -12,6 +12,18 @@ 'condition-urlpattern-string-source-network': [ {condition: {urlPattern: '/**/direct.txt'}, source: 'network'}, ], + 'condition-urlpattern-constructed-ignore-case-source-network': [{ + condition: { + urlPattern: new URLPattern( + {pathname: '/**/DiReCT.TxT'}, + {ignoreCase: true}) + }, + source: 'network' + }], + 'condition-urlpattern-constructed-respect-case-source-network': [{ + condition: {urlPattern: new URLPattern({pathname: '/**/DiReCT.TxT'})}, + source: 'network' + }], 'condition-request-source-network': [{condition: {requestMode: 'no-cors'}, source: 'network'}], 'condition-or-source-network': [{
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-main-resource.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-main-resource.https.html index 523ececf..1673b97 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-main-resource.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-main-resource.https.html
@@ -11,6 +11,10 @@ <script> const SCRIPT = 'resources/static-router-sw.js'; const ROUTER_RULE_KEY = 'condition-urlpattern-constructed-source-network'; +const ROUTER_RULE_KEY_IGNORE_CASE = + 'condition-urlpattern-constructed-ignore-case-source-network'; +const ROUTER_RULE_KEY_RESPECT_CASE = + 'condition-urlpattern-constructed-respect-case-source-network'; const SCOPE = 'resources/'; const REGISTERED_ROUTE = 'resources/direct.txt'; const NON_REGISTERED_ROUTE = 'resources/simple.html'; @@ -48,6 +52,19 @@ assert_equals(iwin.document.body.innerText, "Network\n"); }, 'Main resource load matched with the condition'); +iframeTest(REGISTERED_ROUTE, ROUTER_RULE_KEY_IGNORE_CASE, async (t, iwin, worker) => { + const fetched_urls = await get_fetched_urls(worker); + const {requests} = fetched_urls.data; + assert_equals(requests.length, 0); + assert_equals(iwin.document.body.innerText, "Network\n"); +}, 'Main resource load matched with the ignore case condition'); + +iframeTest(REGISTERED_ROUTE, ROUTER_RULE_KEY_RESPECT_CASE, async (t, iwin, worker) => { + const fetched_urls = await get_fetched_urls(worker); + const {requests} = fetched_urls.data; + assert_equals(requests.length, 1); +}, 'Main resource load matched without the ignore case condition'); + iframeTest(NON_REGISTERED_ROUTE, ROUTER_RULE_KEY, async (t, iwin, worker) => { const fetched_urls = await get_fetched_urls(worker); const {requests} = fetched_urls.data;
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-subresource.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-subresource.https.html index 1fd3880..6154c38 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-subresource.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/tentative/static-router/static-router-subresource.https.html
@@ -10,6 +10,10 @@ const SCRIPT = 'resources/static-router-sw.js'; const ROUTER_RULE_KEY_URL_PATTERN_CONSTRUCTED = 'condition-urlpattern-constructed-source-network'; +const ROUTER_RULE_KEY_URL_PATTERN_CONSTRUCTED_IGNORE_CASE = + 'condition-urlpattern-constructed-ignore-case-source-network'; +const ROUTER_RULE_KEY_URL_PATTERN_CONSTRUCTED_RESPECT_CASE = + 'condition-urlpattern-constructed-respect-case-source-network'; const ROUTER_RULE_KEY_URL_PATTERN_URLPATTERNINIT = 'condition-urlpattern-urlpatterninit-source-network'; const ROUTER_RULE_KEY_URL_PATTERN_STRING = @@ -89,6 +93,18 @@ assert_equals(response.type, 'opaque'); }, 'Subresource cross origin load matched with URLPattern condition via constructed object'); +iframeTest(TXT_FILE, ROUTER_RULE_KEY_URL_PATTERN_CONSTRUCTED_IGNORE_CASE, async (t, iwin) => { + const rnd = randomString(); + const response = await iwin.fetch('?nonce=' + rnd); + assert_equals(await response.text(), "Network\n"); +}, 'Subresource load matched with ignoreCase URLPattern condition'); + +iframeTest(TXT_FILE, ROUTER_RULE_KEY_URL_PATTERN_CONSTRUCTED_RESPECT_CASE, async (t, iwin) => { + const rnd = randomString(); + const response = await iwin.fetch('?nonce=' + rnd); + assert_equals(await response.text(), rnd); +}, 'Subresource load matched without ignoreCase URLPattern condition'); + iframeTest(TXT_FILE, ROUTER_RULE_KEY_URL_PATTERN_URLPATTERNINIT, async (t, iwin) => { const rnd = randomString(); const response = await iwin.fetch('?nonce=' + rnd);
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js index 687f6a4..56ab603 100644 --- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/resources/utils.js
@@ -29,6 +29,9 @@ while (this.#active) { // Add the "keepalive" option to avoid fetch() results in unhandled // rejection with fetch abortion due to window.close(). + // TODO(crbug.com/1356128): After this migration, "keepalive" will not + // be able to extend the lifetime of a Document, such that it cannot be + // used here to guarantee the promise resolution. const messages = await (await fetch(this.#url, {keepalive: true})).json(); for (const {data, id} of messages) { if (!this.#ids.has(id))
diff --git a/third_party/blink/web_tests/fast/css/annotated-regions-expected.txt b/third_party/blink/web_tests/fast/css/annotated-regions-expected.txt index 49bfba6..b99c8ffd 100644 --- a/third_party/blink/web_tests/fast/css/annotated-regions-expected.txt +++ b/third_party/blink/web_tests/fast/css/annotated-regions-expected.txt
@@ -12,6 +12,12 @@ PASS nonDraggableRegions() is '45,25+30x10' PASS draggableRegions() is '20,10+100x60' PASS nonDraggableRegions() is '20,10+60x20' +PASS draggableRegions() is '' +PASS nonDraggableRegions() is '' +PASS draggableRegions() is '' +PASS nonDraggableRegions() is '' +PASS draggableRegions() is '' +PASS nonDraggableRegions() is '' PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/blink/web_tests/fast/css/annotated-regions.html b/third_party/blink/web_tests/fast/css/annotated-regions.html index e9042b4..fb8f826e 100644 --- a/third_party/blink/web_tests/fast/css/annotated-regions.html +++ b/third_party/blink/web_tests/fast/css/annotated-regions.html
@@ -50,6 +50,10 @@ } function startTest() { + // Verify that app regions are correctly collected when the frame supports + // app regions. + internals.SetSupportsAppRegion(true); + shouldBe("draggableRegions()", "''"); shouldBe("nonDraggableRegions()", "''"); @@ -69,6 +73,26 @@ shouldBe("draggableRegions()", "'20,10+100x60'"); shouldBe("nonDraggableRegions()", "'20,10+60x20'"); + // Verify that app regions are reset when the frame does not support + // app regions. + internals.SetSupportsAppRegion(false); + shouldBe("draggableRegions()", "''"); + shouldBe("nonDraggableRegions()", "''"); + + draggable.classList.remove('drag'); + draggable.classList.remove('nodrag'); + + // App regions should continue to be empty when new app regions are added + // or resized. + draggable.classList.add("drag"); + nondraggable.classList.add('nodrag'); + shouldBe("draggableRegions()", "''"); + shouldBe("nonDraggableRegions()", "''"); + + draggable.classList.add('transform'); + shouldBe("draggableRegions()", "''"); + shouldBe("nonDraggableRegions()", "''"); + finishJSTest(); }
diff --git a/third_party/blink/web_tests/fast/peerconnection/RTCEncodedVideoFrame-capture-timestamp-id.html b/third_party/blink/web_tests/fast/peerconnection/RTCEncodedVideoFrameMetadata-timestamp.html similarity index 85% rename from third_party/blink/web_tests/fast/peerconnection/RTCEncodedVideoFrame-capture-timestamp-id.html rename to third_party/blink/web_tests/fast/peerconnection/RTCEncodedVideoFrameMetadata-timestamp.html index 2db7d2c..81262cf 100644 --- a/third_party/blink/web_tests/fast/peerconnection/RTCEncodedVideoFrame-capture-timestamp-id.html +++ b/third_party/blink/web_tests/fast/peerconnection/RTCEncodedVideoFrameMetadata-timestamp.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>Test RTCEncodedVideoFrame.capture_time_identifier_ms in a RTCPeerConnection</title> +<title>Test RTCEncodedVideoFrameMetadata.timestamp matches a unencoded frame timestamp</title> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="resources/RTCPeerConnection-helper.js"></script> @@ -37,6 +37,6 @@ trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable); const metadata = (await senderReader.read()).value.getMetadata(); -assert_equals(originalTimestamp, metadata.captureTimestamp); -}, "captureTimestamp identifier is propagated from VideoFrame to RTCEncodedVideoFrame"); +assert_equals(originalTimestamp, metadata.timestamp); +}, "timestamp identifier is propagated from VideoFrame to RTCEncodedVideoFrame"); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-pagehide-handler-expected.txt b/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-pagehide-handler-expected.txt new file mode 100644 index 0000000..a44def3 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-pagehide-handler-expected.txt
@@ -0,0 +1 @@ +This test triggers an pagehide handler that starts an image load in a different frame (and deletes both frames), but ensures the main frame is not destroyed. We pass if we don't crash.
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-pagehide-handler.html b/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-pagehide-handler.html new file mode 100644 index 0000000..cd76c3e --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-pagehide-handler.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + +<body> + <script> + if (window.testRunner) { + testRunner.dumpAsText(); + testRunner.waitUntilDone(); + } + + function test() { + document.getElementsByTagName("body")[0].removeChild(document.getElementById("target")); + } + + function finish() { + setTimeout(function () { + if (window.testRunner) + testRunner.notifyDone(); + }, 300); + } + </script> + <iframe id="target" name="target" src="resources/image-load-in-subframe-pagehide-handler-helper.html"></iframe> + This test triggers an pagehide handler that starts an image load in a different frame (and deletes both frames), but + ensures the main frame is not destroyed. We pass if we don't crash. +</body> + +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-unload-handler-expected.txt b/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-unload-handler-expected.txt deleted file mode 100644 index f817783..0000000 --- a/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-unload-handler-expected.txt +++ /dev/null
@@ -1 +0,0 @@ -This test triggers an unload handler that starts an image load in a different frame (and deletes both frames), but ensures the main frame is not destroyed. We pass if we don't crash.
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-unload-handler.html b/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-unload-handler.html deleted file mode 100644 index c00aa79e..0000000 --- a/third_party/blink/web_tests/http/tests/navigation/image-load-in-subframe-unload-handler.html +++ /dev/null
@@ -1,23 +0,0 @@ -<html> -<body> -<script> - if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - function test() { - document.getElementsByTagName("body")[0].removeChild(document.getElementById("target")); - } - - function finish() { - setTimeout(function() { - if (window.testRunner) - testRunner.notifyDone(); - }, 300); - } -</script> -<iframe id="target" name="target" src="resources/image-load-in-subframe-unload-handler-helper.html"></iframe> -This test triggers an unload handler that starts an image load in a different frame (and deletes both frames), but ensures the main frame is not destroyed. We pass if we don't crash. -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/navigation/resources/image-load-in-subframe-unload-handler-helper.html b/third_party/blink/web_tests/http/tests/navigation/resources/image-load-in-subframe-pagehide-handler-helper.html similarity index 85% rename from third_party/blink/web_tests/http/tests/navigation/resources/image-load-in-subframe-unload-handler-helper.html rename to third_party/blink/web_tests/http/tests/navigation/resources/image-load-in-subframe-pagehide-handler-helper.html index f289000..30af3d4d 100644 --- a/third_party/blink/web_tests/http/tests/navigation/resources/image-load-in-subframe-unload-handler-helper.html +++ b/third_party/blink/web_tests/http/tests/navigation/resources/image-load-in-subframe-pagehide-handler-helper.html
@@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <body> <script> @@ -11,6 +12,6 @@ window.top.finish(); } </script> -<iframe src="subframe-with-unload-handler-in-parent.html"> +<iframe src="subframe-with-pagehide-handler-in-parent.html"> </body> </html>
diff --git a/third_party/blink/web_tests/http/tests/navigation/resources/subframe-with-pagehide-handler-in-parent.html b/third_party/blink/web_tests/http/tests/navigation/resources/subframe-with-pagehide-handler-in-parent.html new file mode 100644 index 0000000..8886c14 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/resources/subframe-with-pagehide-handler-in-parent.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + +<head> + <script> + function unload() { + window.parent.imageLoad(); + } + + function load() { + window.top.test(); + } + </script> +</head> + +<body onload="load();" onpagehide="unload();"> + This subframe has an pagehide handler. +</body> + +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/navigation/resources/subframe-with-unload-handler-in-parent.html b/third_party/blink/web_tests/http/tests/navigation/resources/subframe-with-unload-handler-in-parent.html deleted file mode 100644 index eec5d3e..0000000 --- a/third_party/blink/web_tests/http/tests/navigation/resources/subframe-with-unload-handler-in-parent.html +++ /dev/null
@@ -1,16 +0,0 @@ -<html> -<head> -<script> -function unload() { - window.parent.imageLoad(); -} - -function load() { - window.top.test(); -} -</script> -</head> -<body onload="load();" onunload="unload();"> -This subframe has an unload handler. -</body> -</html>
diff --git a/third_party/blink/web_tests/virtual/deprecate-unload/external/wpt/html/browsers/browsing-the-web/unloading-documents/001-expected.txt b/third_party/blink/web_tests/virtual/deprecate-unload/external/wpt/html/browsers/browsing-the-web/unloading-documents/001-expected.txt new file mode 100644 index 0000000..2c74bc75f --- /dev/null +++ b/third_party/blink/web_tests/virtual/deprecate-unload/external/wpt/html/browsers/browsing-the-web/unloading-documents/001-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] document.open in unload + assert_equals: expected "0123456789" but got "01238" +Harness: the test ran to completion. +
diff --git a/third_party/catapult b/third_party/catapult index b142d41..d12e688 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit b142d415308e1f3ace94f0f39807bf0198ee004f +Subproject commit d12e6887dd534569117c06f92e8c69c91e0ad12b
diff --git a/third_party/chromium-variations b/third_party/chromium-variations index 510ec37..62652a4 160000 --- a/third_party/chromium-variations +++ b/third_party/chromium-variations
@@ -1 +1 @@ -Subproject commit 510ec37c3f2bf8431f8c6f1a573d6826ed01d9e6 +Subproject commit 62652a482c1bc8658057a7fa7b216f638d0dfaae
diff --git a/third_party/cros-components/src b/third_party/cros-components/src index b1b1b0b..b7deff8 160000 --- a/third_party/cros-components/src +++ b/third_party/cros-components/src
@@ -1 +1 @@ -Subproject commit b1b1b0b6ff08289f3f5d960947aa12db68775d41 +Subproject commit b7deff896ee3186e7d33a52ddde07da2400de2ad
diff --git a/third_party/dawn b/third_party/dawn index 109e648..3c117aa 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 109e648f2f452424d2d1d0b1eba1e1b9fe036645 +Subproject commit 3c117aa551537c3e7cc0f8cbb05d85fe76d466fc
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index d4775b3..14464a6 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit d4775b3834d55829a429cf165089e92261a9e426 +Subproject commit 14464a6787e9a358a6acdc532568e6fe3a347344
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 7781523..c7e8227 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 7781523a3fc8f16c45a382676e73b1f7f28a58e5 +Subproject commit c7e8227f786e657d8f82d6e9f1de859ed60280df
diff --git a/third_party/pdfium b/third_party/pdfium index cb1cd2f..dda631d 160000 --- a/third_party/pdfium +++ b/third_party/pdfium
@@ -1 +1 @@ -Subproject commit cb1cd2f12898d7cdc0d9435be2244ce27f88afe3 +Subproject commit dda631d81103d0af8fa2fe4bd81e9da08435f989
diff --git a/third_party/skia b/third_party/skia index 3a3475d..9d220eb 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 3a3475d12f220b795821eabae517ab7cb6f12c9f +Subproject commit 9d220ebe40a0e8537f3e37d8ac1fbe4ac4dfa43a
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src index 7a6ef73..666950d 160000 --- a/third_party/webgpu-cts/src +++ b/third_party/webgpu-cts/src
@@ -1 +1 @@ -Subproject commit 7a6ef7301b5d84f751b483f9d5466b3696749c26 +Subproject commit 666950d6de30c9c26773208b0f861463b25ae37c
diff --git a/third_party/webrtc b/third_party/webrtc index 21edbe5..e6df126b 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit 21edbe5d0dc7a506ff42b858969d16d0cbdd3a0b +Subproject commit e6df126b798c0644010afeaddeb2e13053d8f192
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index fbcaf3b..4e01d9d3 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@ # https://chromium.googlesource.com/chromium/src/+/main/docs/updating_clang.md # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. -CLANG_REVISION = 'llvmorg-18-init-12938-geb1d5065' +CLANG_REVISION = 'llvmorg-18-init-14420-gea3a3b25' CLANG_SUB_REVISION = 1 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index 96530ad..494cc1fa 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1916,19 +1916,24 @@ </summary> </histogram> -<histogram name="Blink.Fetch.RequestResourceTime2{Scheme}" units="microseconds" - expires_after="2023-05-02"> +<histogram name="Blink.Fetch.RequestResourceTime2{SchemeOrPreload}" + units="microseconds" expires_after="2024-03-12"> <owner>cduvall@chromium.org</owner> <owner>csharrison@chromium.org</owner> + <owner>chrome-loading@google.com</owner> <summary> The total microseconds spent in ResourceFetcher::requestResource for - {Scheme}. + {SchemeOrPreload}. This histogram only records metrics on machines with high-resolution clocks. + + Warning: this histogram was expired from 2023-05-02 to 2023-12-12; data may + be missing. </summary> - <token key="Scheme"> + <token key="SchemeOrPreload"> <variant name="" summary="all URLs"/> <variant name=".Data" summary="data URLs"/> + <variant name=".Preload" summary="preloaded URLs"/> </token> </histogram> @@ -2701,6 +2706,23 @@ </summary> </histogram> +<histogram + name="Blink.LCPP.NavigationToStartPreload.MainFrame.{SubresourceType}.Time" + units="ms" expires_after="2024-02-01"> + <owner>chikamune@chromium.org</owner> + <owner>yyanagisawa@chromium.org</owner> + <owner>kouhei@chromium.org</owner> + <summary> + Record when the page's main frame starts preloading {SubresourceType}. + Measures the duration between when the navigation starts, to when preloading + subresource is started. + </summary> + <token key="SubresourceType"> + <variant name="EachSubresource" summary="each subresources"/> + <variant name="FirstSubresource" summary="the first subresource"/> + </token> +</histogram> + <histogram name="Blink.LCPP.PotentiallyLCPResourcePriorityBoosts" units="count" expires_after="2024-01-27"> <owner>kouhei@chromium.org</owner> @@ -3164,13 +3186,29 @@ </summary> </histogram> +<histogram name="Blink.PreloadRequestStartDuration" units="microseconds" + expires_after="2024-03-12"> + <owner>sisidovski@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + Measures the time from the time when PreloadRequest::Start is called to when + PreloadRequest::Start is finished. + + This histogram only records metrics on machines with high-resolution clocks. + </summary> +</histogram> + <histogram name="Blink.PreloadRequestWaitTime" units="ms" - expires_after="2023-10-22"> + expires_after="2024-03-12"> <owner>cduvall@chromium.org</owner> <owner>swarm-team@google.com</owner> + <owner>chrome-loading@google.com</owner> <summary> Measures the time from the creation of a PreloadRequest to when PreloadRequest::Start is called. Logged for each PreloadRequest::Start call. + + Warning: this histogram was expired from 2023-10-22 to 2023-12-12; data may + be missing. </summary> </histogram> @@ -3291,6 +3329,9 @@ <owner>jam@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> + Blink.ScanAndPreloadTime2 is the newer one of this histogram, which records + the time with microseconds. + Measures the time it takes to scan and preload subresources for a document in a {FrameType}. Logged every time the {IsInitial} preload scan is performed. @@ -3308,6 +3349,31 @@ </token> </histogram> +<histogram name="Blink.ScanAndPreloadTime2{Task}.{FrameType}.{IsInitial}" + units="microseconds" expires_after="2024-03-13"> + <owner>sisidovski@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + Measures the time it takes to {Task} for a document in a {FrameType}. Logged + every time the {IsInitial} preload scan is performed. + + This histogram only records metrics on machines with high-resolution clocks. + </summary> + <token key="Task"> + <variant name="" summary="scan and preload subresources"/> + <variant name=".Preload" summary="preload subresources"/> + <variant name=".Scan" summary="scan"/> + </token> + <token key="FrameType"> + <variant name="MainFrame"/> + <variant name="Subframe"/> + </token> + <token key="IsInitial"> + <variant name="Initial"/> + <variant name="NonInitial"/> + </token> +</histogram> + <histogram name="Blink.ScanPendingActivityDuration" units="ms" expires_after="M85"> <owner>haraken@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index 63cace6..3c53af0 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -3928,17 +3928,6 @@ </summary> </histogram> -<histogram name="Net.QuicSession.ReceivedSettings.EnableExtendedConnect" - enum="Boolean" expires_after="2024-01-21"> - <owner>momoka@google.com</owner> - <owner>ricea@chromium.org</owner> - <owner>src/net/quic/OWNERS</owner> - <summary> - The value of the SETTINGS_ENABLE_CONNECT_PROTOCOL parameter received on an - HTTP/3 connection, if the parameter is not present log false. - </summary> -</histogram> - <histogram name="Net.QuicSession.ReceivedSettings.MaxHeaderListSize2" units="bytes" expires_after="2023-09-24"> <owner>dschinazi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml index 6247873..2f15042 100644 --- a/tools/metrics/histograms/metadata/omnibox/histograms.xml +++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -1614,7 +1614,7 @@ </histogram> <histogram name="Omnibox.SetText.Duration" units="ms" - expires_after="2024-05-26"> + expires_after="2024-06-01"> <owner>peilinwang@google.com</owner> <owner>woa-performance-bugs+jank@google.com</owner> <summary> @@ -1624,7 +1624,7 @@ </histogram> <histogram name="Omnibox.SetText.TextLength" units="characters" - expires_after="2024-06-02"> + expires_after="2024-06-01"> <owner>peilinwang@google.com</owner> <owner>woa-performance-bugs+jank@google.com</owner> <summary> @@ -1634,7 +1634,7 @@ </histogram> <histogram name="Omnibox.setText.TruncatedTooMuch" enum="Boolean" - expires_after="2023-12-24"> + expires_after="2024-06-01"> <owner>peilinwang@google.com</owner> <owner>woa-performance-bugs+jank@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml index bbea9bc2..b9eaa34 100644 --- a/tools/metrics/histograms/metadata/page/histograms.xml +++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -798,6 +798,48 @@ </histogram> <histogram + name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalLoaderCallback" + units="ms" expires_after="2024-03-19"> + <owner>nidhijaju@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time relative to navigation start that a callback for the navigation + loader is last invoked for the main resource of a main frame navigation, for + Google Search page loads. Only recorded for Search navigations that happen + entirely in the foreground. The metric is emitted when the navigation is + completed or the app is backgrounded on Android. + </summary> +</histogram> + +<histogram + name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalRequestStart" + units="ms" expires_after="2024-03-19"> + <owner>nidhijaju@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time relative to navigation start that the final HTTP request is sent + for the main resource of a main frame navigation, for Google Search page + loads. Only recorded for Search navigations that happen entirely in the + foreground. The metric is emitted when the navigation is completed or the + app is backgrounded on Android. + </summary> +</histogram> + +<histogram + name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalResponseStart" + units="ms" expires_after="2024-03-19"> + <owner>nidhijaju@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time relative to navigation start that the headers of the final HTTP + response is received for the main resource of a main frame navigation, for + Google Search page loads. Only recorded for Search navigations that happen + entirely in the foreground. The metric is emitted when the navigation is + completed or the app is backgrounded on Android. + </summary> +</histogram> + +<histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFirstLoaderCallback" units="ms" expires_after="2024-03-19"> <owner>kouhei@chromium.org</owner>
diff --git a/tools/polymer/css_to_wrapper_test.py b/tools/polymer/css_to_wrapper_test.py index d20c49e..adeab81 100755 --- a/tools/polymer/css_to_wrapper_test.py +++ b/tools/polymer/css_to_wrapper_test.py
@@ -58,7 +58,7 @@ def testCssToWrapperStylePolymer(self): self._run_test('css_to_wrapper/foo_style.css', 'css_to_wrapper/foo_style.css.ts', - 'css_to_wrapper/foo_style_expected.css.ts') + 'css_to_wrapper/expected/foo_style.css.ts') def testCssToWrapperStyleLit(self): self._run_test('css_to_wrapper/foo_style_lit.css', @@ -68,12 +68,12 @@ def testCssToWrapperStyleNoIncludes(self): self._run_test('css_to_wrapper/foo_no_includes_style.css', 'css_to_wrapper/foo_no_includes_style.css.ts', - 'css_to_wrapper/foo_no_includes_style_expected.css.ts') + 'css_to_wrapper/expected/foo_no_includes_style.css.ts') def testCssToWrapperVarsPolymer(self): self._run_test('css_to_wrapper/foo_vars.css', 'css_to_wrapper/foo_vars.css.ts', - 'css_to_wrapper/foo_vars_expected.css.ts') + 'css_to_wrapper/expected/foo_vars.css.ts') def testCssToWrapperVarsLit(self): self._run_test('css_to_wrapper/foo_vars_lit.css', @@ -83,19 +83,19 @@ def testCssToWrapperMinify(self): self._run_test('css_to_wrapper/foo_style.css', 'css_to_wrapper/foo_style.css.ts', - 'css_to_wrapper/foo_style_expected.min.css.ts', + 'css_to_wrapper/expected/foo_style.min.css.ts', minify=True) def testCssToWrapperUseJs(self): self._run_test('css_to_wrapper/foo_style.css', 'css_to_wrapper/foo_style.css.js', - 'css_to_wrapper/foo_style_expected.css.ts', + 'css_to_wrapper/expected/foo_style.css.ts', use_js=True) def testCssToWrapperSchemeRelative(self): self._run_test('css_to_wrapper/foo_relative_style.css', 'css_to_wrapper/foo_relative_style.css.ts', - 'css_to_wrapper/foo_relative_style_expected.css.ts') + 'css_to_wrapper/expected/foo_relative_style.css.ts') if __name__ == '__main__':
diff --git a/tools/polymer/html_to_wrapper_test.py b/tools/polymer/html_to_wrapper_test.py index eefa4ce..b1dc959 100755 --- a/tools/polymer/html_to_wrapper_test.py +++ b/tools/polymer/html_to_wrapper_test.py
@@ -64,12 +64,12 @@ def testHtmlToWrapperPolymerElement(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts', - 'html_to_wrapper/foo_expected.html.ts') + 'html_to_wrapper/expected/foo.html.ts') def testHtmlToWrapperPolymerElement_Detect(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts', - 'html_to_wrapper/foo_expected.html.ts', + 'html_to_wrapper/expected/foo.html.ts', template='detect') def testHtmlToWrapperLitElement(self): @@ -87,56 +87,56 @@ def testHtmlToWrapperNativeElement(self): self._run_test('html_to_wrapper/foo_native.html', 'html_to_wrapper/foo_native.html.ts', - 'html_to_wrapper/foo_native_expected.html.ts', + 'html_to_wrapper/expected/foo_native.html.ts', template='native') def testHtmlToWrapperNativeElement_Detect(self): self._run_test('html_to_wrapper/foo_native.html', 'html_to_wrapper/foo_native.html.ts', - 'html_to_wrapper/foo_native_expected.html.ts', + 'html_to_wrapper/expected/foo_native.html.ts', template='detect') def testHtmlToWrapperIcons(self): self._run_test('html_to_wrapper/icons.html', 'html_to_wrapper/icons.html.ts', - 'html_to_wrapper/icons_expected.html.ts') + 'html_to_wrapper/expected/icons.html.ts') def testHtmlToWrapper_Minify(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts', - 'html_to_wrapper/foo_expected.min.html.ts', + 'html_to_wrapper/expected/foo.min.html.ts', minify=True) def testHtmlToWrapper_MinifyDetect(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts', - 'html_to_wrapper/foo_expected.min.html.ts', + 'html_to_wrapper/expected/foo.min.html.ts', minify=True, template='detect') def testHtmlToWrapper_UseJs(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.js', - 'html_to_wrapper/foo_expected.html.ts', + 'html_to_wrapper/expected/foo.html.ts', use_js=True) def testHtmlToWrapper_UseJsDetect(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.js', - 'html_to_wrapper/foo_expected.html.ts', + 'html_to_wrapper/expected/foo.html.ts', use_js=True, template='detect') def testHtmlToWrapperSchemeRelative(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts', - 'html_to_wrapper/foo_expected.html.ts', + 'html_to_wrapper/expected/foo.html.ts', scheme='relative') def testHtmlToWrapperSchemeChrome(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts', - 'html_to_wrapper/foo_chrome_expected.html.ts', + 'html_to_wrapper/expected/foo_chrome.html.ts', scheme='chrome')
diff --git a/tools/polymer/tests/css_to_wrapper/foo_no_includes_style_expected.css.ts b/tools/polymer/tests/css_to_wrapper/expected/foo_no_includes_style.css.ts similarity index 100% rename from tools/polymer/tests/css_to_wrapper/foo_no_includes_style_expected.css.ts rename to tools/polymer/tests/css_to_wrapper/expected/foo_no_includes_style.css.ts
diff --git a/tools/polymer/tests/css_to_wrapper/foo_relative_style_expected.css.ts b/tools/polymer/tests/css_to_wrapper/expected/foo_relative_style.css.ts similarity index 100% rename from tools/polymer/tests/css_to_wrapper/foo_relative_style_expected.css.ts rename to tools/polymer/tests/css_to_wrapper/expected/foo_relative_style.css.ts
diff --git a/tools/polymer/tests/css_to_wrapper/foo_style_expected.css.ts b/tools/polymer/tests/css_to_wrapper/expected/foo_style.css.ts similarity index 100% rename from tools/polymer/tests/css_to_wrapper/foo_style_expected.css.ts rename to tools/polymer/tests/css_to_wrapper/expected/foo_style.css.ts
diff --git a/tools/polymer/tests/css_to_wrapper/foo_style_expected.min.css.ts b/tools/polymer/tests/css_to_wrapper/expected/foo_style.min.css.ts similarity index 100% rename from tools/polymer/tests/css_to_wrapper/foo_style_expected.min.css.ts rename to tools/polymer/tests/css_to_wrapper/expected/foo_style.min.css.ts
diff --git a/tools/polymer/tests/css_to_wrapper/foo_vars_expected.css.ts b/tools/polymer/tests/css_to_wrapper/expected/foo_vars.css.ts similarity index 100% rename from tools/polymer/tests/css_to_wrapper/foo_vars_expected.css.ts rename to tools/polymer/tests/css_to_wrapper/expected/foo_vars.css.ts
diff --git a/tools/polymer/tests/html_to_wrapper/foo_expected.html.ts b/tools/polymer/tests/html_to_wrapper/expected/foo.html.ts similarity index 100% rename from tools/polymer/tests/html_to_wrapper/foo_expected.html.ts rename to tools/polymer/tests/html_to_wrapper/expected/foo.html.ts
diff --git a/tools/polymer/tests/html_to_wrapper/foo_expected.min.html.ts b/tools/polymer/tests/html_to_wrapper/expected/foo.min.html.ts similarity index 100% rename from tools/polymer/tests/html_to_wrapper/foo_expected.min.html.ts rename to tools/polymer/tests/html_to_wrapper/expected/foo.min.html.ts
diff --git a/tools/polymer/tests/html_to_wrapper/foo_chrome_expected.html.ts b/tools/polymer/tests/html_to_wrapper/expected/foo_chrome.html.ts similarity index 100% rename from tools/polymer/tests/html_to_wrapper/foo_chrome_expected.html.ts rename to tools/polymer/tests/html_to_wrapper/expected/foo_chrome.html.ts
diff --git a/tools/polymer/tests/html_to_wrapper/foo_native_expected.html.ts b/tools/polymer/tests/html_to_wrapper/expected/foo_native.html.ts similarity index 100% rename from tools/polymer/tests/html_to_wrapper/foo_native_expected.html.ts rename to tools/polymer/tests/html_to_wrapper/expected/foo_native.html.ts
diff --git a/tools/polymer/tests/html_to_wrapper/icons_expected.html.ts b/tools/polymer/tests/html_to_wrapper/expected/icons.html.ts similarity index 100% rename from tools/polymer/tests/html_to_wrapper/icons_expected.html.ts rename to tools/polymer/tests/html_to_wrapper/expected/icons.html.ts
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py index cbaa4c6b..3143842 100755 --- a/tools/rust/build_rust.py +++ b/tools/rust/build_rust.py
@@ -749,6 +749,11 @@ '81cd7c5b11766ed1e3214a2233371fb6d72ed89c') # TODO: Remove once + # https://github.com/rust-lang/rust/pull/118610 has been merged. + GitCherryPick(RUST_SRC_DIR, 'https://github.com/rust-lang/rust.git', + 'b378059e6b2573c5356423fa31d184a89a3b6029') + + # TODO: Remove once # https://github.com/rust-lang/rust/pull/118818 has been merged. GitCherryPick(RUST_SRC_DIR, 'https://github.com/rust-lang/rust.git', 'a0c5079889b1f86dd9e246d8863a5c8b44fbdb78')
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc index 3d831e9d..eca2ea8 100644 --- a/ui/gfx/image/image.cc +++ b/ui/gfx/image/image.cc
@@ -122,13 +122,8 @@ }; ImageStorage::ImageStorage(Image::RepresentationType default_type) - : default_representation_type_(default_type) -#if BUILDFLAG(IS_MAC) - , - default_representation_color_space_(base::mac::GetGenericRGBColorSpace()) -#endif // BUILDFLAG(IS_MAC) -{ -} + : default_representation_type_(default_type) {} + ImageStorage::~ImageStorage() = default; Image::RepresentationType ImageStorage::default_representation_type() const { @@ -316,22 +311,19 @@ const internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false); if (!rep) { std::unique_ptr<internal::ImageRep> scoped_rep; - CGColorSpaceRef default_representation_color_space = - storage()->default_representation_color_space(); switch (DefaultRepresentationType()) { case kImageRepPNG: { const internal::ImageRepPNG* png_rep = GetRepresentation(kImageRepPNG, true)->AsImageRepPNG(); - scoped_rep = internal::MakeImageRepCocoa(internal::NSImageFromPNG( - png_rep->image_reps(), default_representation_color_space)); + scoped_rep = internal::MakeImageRepCocoa( + internal::NSImageFromPNG(png_rep->image_reps())); break; } case kImageRepSkia: { const internal::ImageRepSkia* skia_rep = GetRepresentation(kImageRepSkia, true)->AsImageRepSkia(); - NSImage* image = NSImageFromImageSkiaWithColorSpace(*skia_rep->image(), - default_representation_color_space); + NSImage* image = NSImageFromImageSkia(*skia_rep->image()); scoped_rep = internal::MakeImageRepCocoa(image); break; } @@ -453,13 +445,6 @@ return GetRepresentation(DefaultRepresentationType(), true)->Size(); } -#if BUILDFLAG(IS_MAC) -void Image::SetSourceColorSpace(CGColorSpaceRef color_space) { - if (storage()) - storage()->set_default_representation_color_space(color_space); -} -#endif // BUILDFLAG(IS_MAC) - Image::RepresentationType Image::DefaultRepresentationType() const { CHECK(storage()); return storage()->default_representation_type();
diff --git a/ui/gfx/image/image.h b/ui/gfx/image/image.h index 9cb9b1f3..c3d1c85a 100644 --- a/ui/gfx/image/image.h +++ b/ui/gfx/image/image.h
@@ -163,7 +163,8 @@ // Set the default representation's color space. This is used for converting // to NSImage. This is used to compensate for PNGCodec not writing or reading // colorspace ancillary chunks. (sRGB, iCCP). - void SetSourceColorSpace(CGColorSpaceRef color_space); + // TODO(https://crbug.com/1495334): Remove callers of this function. + void SetSourceColorSpace(CGColorSpaceRef color_space) {} #endif // BUILDFLAG(IS_MAC) private:
diff --git a/ui/gfx/image/image_internal.h b/ui/gfx/image/image_internal.h index 1226b33..11fdbbb 100644 --- a/ui/gfx/image/image_internal.h +++ b/ui/gfx/image/image_internal.h
@@ -90,14 +90,8 @@ const ImageRep* AddRepresentation(std::unique_ptr<ImageRep> rep) const; #if BUILDFLAG(IS_MAC) - void set_default_representation_color_space(CGColorSpaceRef color_space) { - DCHECK(IsOnValidSequence()); - default_representation_color_space_ = color_space; - } - CGColorSpaceRef default_representation_color_space() const { - DCHECK(IsOnValidSequence()); - return default_representation_color_space_; - } + // TODO(https://crbug.com/1495334): Remove callers of this function. + void set_default_representation_color_space(CGColorSpaceRef color_space) {} #endif // BUILDFLAG(IS_MAC) private: @@ -109,14 +103,6 @@ // exist in the |representations_| map. Image::RepresentationType default_representation_type_; -#if BUILDFLAG(IS_MAC) - // The default representation's colorspace. This is used for converting to - // NSImage. This field exists to compensate for PNGCodec not writing or - // reading colorspace ancillary chunks. (sRGB, iCCP). - // Not owned. - CGColorSpaceRef default_representation_color_space_; -#endif // BUILDFLAG(IS_MAC) - // All the representations of an Image. Size will always be at least one, with // more for any converted representations. mutable std::map<Image::RepresentationType,
diff --git a/ui/gfx/image/image_mac.mm b/ui/gfx/image/image_mac.mm index 0beedf45..8c1e9c86 100644 --- a/ui/gfx/image/image_mac.mm +++ b/ui/gfx/image/image_mac.mm
@@ -97,8 +97,7 @@ return refcounted_bytes; } -NSImage* NSImageFromPNG(const std::vector<gfx::ImagePNGRep>& image_png_reps, - CGColorSpaceRef color_space) { +NSImage* NSImageFromPNG(const std::vector<gfx::ImagePNGRep>& image_png_reps) { if (image_png_reps.empty()) { LOG(ERROR) << "Unable to decode PNG."; return GetErrorNSImage(); @@ -116,24 +115,6 @@ LOG(ERROR) << "Unable to decode PNG at " << image_png_rep.scale << "."; return GetErrorNSImage(); } - - // PNGCodec ignores colorspace related ancillary chunks (sRGB, iCCP). Ignore - // colorspace information when decoding directly from PNG to an NSImage so - // that the conversions: PNG -> SkBitmap -> NSImage and PNG -> NSImage - // produce visually similar results. - CGColorSpaceModel decoded_color_space_model = - CGColorSpaceGetModel(ns_image_rep.colorSpace.CGColorSpace); - CGColorSpaceModel color_space_model = CGColorSpaceGetModel(color_space); - if (decoded_color_space_model == color_space_model) { - NSColorSpace* ns_color_space = - [[NSColorSpace alloc] initWithCGColorSpace:color_space]; - NSBitmapImageRep* ns_retagged_image_rep = - [ns_image_rep - bitmapImageRepByRetaggingWithColorSpace:ns_color_space]; - if (ns_retagged_image_rep && ns_retagged_image_rep != ns_image_rep) - ns_image_rep = ns_retagged_image_rep; - } - if (!image) { float scale = image_png_rep.scale; NSSize image_size = NSMakeSize(ns_image_rep.pixelsWide / scale,
diff --git a/ui/gfx/image/image_platform.h b/ui/gfx/image/image_platform.h index 766b927..590b0be1 100644 --- a/ui/gfx/image/image_platform.h +++ b/ui/gfx/image/image_platform.h
@@ -46,8 +46,14 @@ #elif BUILDFLAG(IS_MAC) scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromNSImage( NSImage* nsimage); -NSImage* NSImageFromPNG(const std::vector<ImagePNGRep>& image_png_reps, - CGColorSpaceRef color_space); + +NSImage* NSImageFromPNG(const std::vector<ImagePNGRep>& image_png_reps); + +// TODO(https://crbug.com/1495334): Remove callers to this function. +inline NSImage* NSImageFromPNG(const std::vector<ImagePNGRep>& image_png_reps, + CGColorSpaceRef color_space) { + return NSImageFromPNG(image_png_reps); +} NSImage* NSImageOfImageRepCocoa(const ImageRepCocoa* image_rep); std::unique_ptr<ImageRep> MakeImageRepCocoa(NSImage* image);
diff --git a/ui/gfx/image/image_skia_util_mac.h b/ui/gfx/image/image_skia_util_mac.h index 1dff65ea..22fa57c 100644 --- a/ui/gfx/image/image_skia_util_mac.h +++ b/ui/gfx/image/image_skia_util_mac.h
@@ -30,10 +30,15 @@ // Converts to NSImage from ImageSkia. Uses the sRGB color space. GFX_EXPORT NSImage* NSImageFromImageSkia(const gfx::ImageSkia& image_skia); -// Converts to NSImage from given ImageSkia and a color space. -GFX_EXPORT NSImage* NSImageFromImageSkiaWithColorSpace( +// Converts to NSImage from given ImageSkia. +GFX_EXPORT NSImage* NSImageFromImageSkia(const gfx::ImageSkia& image_skia); + +// TODO(https://crbug.com/1495334): Remove callers to this function. +inline NSImage* NSImageFromImageSkiaWithColorSpace( const gfx::ImageSkia& image_skia, - CGColorSpaceRef color_space); + CGColorSpaceRef color_space) { + return NSImageFromImageSkia(image_skia); +} } // namespace gfx
diff --git a/ui/gfx/image/image_skia_util_mac.mm b/ui/gfx/image/image_skia_util_mac.mm index e61cfc0..43870ef65 100644 --- a/ui/gfx/image/image_skia_util_mac.mm +++ b/ui/gfx/image/image_skia_util_mac.mm
@@ -69,9 +69,8 @@ NSImageRep* ns_image_rep = GetNSImageRepWithPixelSize(image, desired_size_for_scale); - SkBitmap bitmap(skia::NSImageRepToSkBitmapWithColorSpace( - ns_image_rep, desired_size_for_scale, false, - base::mac::GetSRGBColorSpace())); + SkBitmap bitmap(skia::NSImageRepToSkBitmap(ns_image_rep, + desired_size_for_scale, false)); if (bitmap.isNull()) continue; @@ -81,12 +80,6 @@ } NSImage* NSImageFromImageSkia(const gfx::ImageSkia& image_skia) { - return NSImageFromImageSkiaWithColorSpace(image_skia, - base::mac::GetSRGBColorSpace()); -} - -NSImage* NSImageFromImageSkiaWithColorSpace(const gfx::ImageSkia& image_skia, - CGColorSpaceRef color_space) { if (image_skia.isNull()) return nil; @@ -94,8 +87,7 @@ image_skia.EnsureRepsForSupportedScales(); std::vector<gfx::ImageSkiaRep> image_reps = image_skia.image_reps(); for (const auto& rep : image_reps) { - [image addRepresentation:skia::SkBitmapToNSBitmapImageRepWithColorSpace( - rep.GetBitmap(), color_space)]; + [image addRepresentation:skia::SkBitmapToNSBitmapImageRep(rep.GetBitmap())]; } image.size = NSMakeSize(image_skia.width(), image_skia.height());
diff --git a/ui/gfx/image/image_unittest_util.cc b/ui/gfx/image/image_unittest_util.cc index cdbc16d..10d4cd5 100644 --- a/ui/gfx/image/image_unittest_util.cc +++ b/ui/gfx/image/image_unittest_util.cc
@@ -205,8 +205,7 @@ skia::SkBitmapToUIImageWithColorSpace(bitmap, scale, color_space.get()); return image; #elif BUILDFLAG(IS_MAC) - NSImage* image = skia::SkBitmapToNSImageWithColorSpace( - bitmap, base::mac::GetGenericRGBColorSpace()); + NSImage* image = skia::SkBitmapToNSImage(bitmap); return image; #else return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index d61030f..dfae20e 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -4175,7 +4175,9 @@ testing::NiceMock<MockWaylandPlatformWindowDelegate> delegate_2; auto toplevel = CreateWaylandWindowWithParams( PlatformWindowType::kWindow, gfx::Rect(10, 10, 200, 200), &delegate_2); - toplevel->HandleAuraToplevelConfigure(0, 0, 0, 0, {false, false, true}); + toplevel->HandleAuraToplevelConfigure( + 0, 0, 0, 0, + {.is_maximized = false, .is_fullscreen = false, .is_activated = true}); toplevel->HandleSurfaceConfigure(2); EXPECT_EQ(gfx::Rect(10, 10, 200, 200), toplevel->GetBoundsInDIP()); }
diff --git a/ui/webui/resources/cr_components/most_visited/most_visited.ts b/ui/webui/resources/cr_components/most_visited/most_visited.ts index 33b8c62..8cf75bf 100644 --- a/ui/webui/resources/cr_components/most_visited/most_visited.ts +++ b/ui/webui/resources/cr_components/most_visited/most_visited.ts
@@ -425,18 +425,15 @@ } /** - * If a pointer is over a tile rect that is different from the one being - * dragged, the dragging tile is moved to the new position. The reordering - * is done in the DOM and the by the |reorderMostVisitedTile()| call. This is - * done to prevent flicking between the time when the tiles are moved back to - * their original positions (by removing position absolute) and when the - * tiles are updated via the |setMostVisitedInfo| handler. + * This method is always called when the drag and drop was finished. + * If the tiles were reordered successfully, there should be a tile with the + * "dropped" class. * * |reordering_| is not set to false when the tiles are reordered. The callers * will need to set it to false. This is necessary to handle a mouse drag * issue. */ - private dragEnd_(x: number, y: number) { + private dragEnd_() { if (!this.customLinksEnabled_) { this.reordering_ = false; return; @@ -446,15 +443,50 @@ const dragElement = this.shadowRoot!.querySelector<HTMLElement>('.tile.dragging'); - if (!dragElement) { + const droppedElement = + this.shadowRoot!.querySelector<HTMLElement>('.tile.dropped'); + + if (!dragElement && !droppedElement) { this.reordering_ = false; return; } - dragElement.classList.remove('dragging'); + if (dragElement) { + dragElement.classList.remove('dragging'); - this.tileElements_.forEach(el => resetTilePosition(el)); - resetTilePosition(this.$.addShortcut); + this.tileElements_.forEach(el => resetTilePosition(el)); + resetTilePosition(this.$.addShortcut); + } else if (droppedElement) { + droppedElement.classList.remove('dropped'); + + // Note that resetTilePosition has already been called on drop_. + } + } + + /** + * This method is called on "drop" events (i.e. when the user drops the tile + * on a valid region.) + * + * If a pointer is over a tile rect that is different from the one being + * dragged, the dragging tile is moved to the new position. The reordering is + * done in the DOM and by the |reorderMostVisitedTile()| call. This is done to + * prevent flicking between the time when the tiles are moved back to their + * original positions (by removing position absolute) and when the tiles are + * updated via the |setMostVisitedInfo| handler. + * + * We remove the "dragging" class in this method, and add "dropped" to + * indicate that the dragged tile was successfully dropped. + */ + private drop_(x: number, y: number) { + if (!this.customLinksEnabled_) { + return; + } + + const dragElement = + this.shadowRoot!.querySelector<HTMLElement>('.tile.dragging'); + if (!dragElement) { + return; + } const dragIndex = (this.$.tiles.modelForElement(dragElement) as unknown as { index: number, @@ -480,6 +512,16 @@ }, ]); this.pageHandler_.reorderMostVisitedTile(draggingTile.url, dropIndex); + + // Remove the "dragging" class here to prevent flickering. + dragElement.classList.remove('dragging'); + + // Add "dropped" class so that we can skip disabling `reordering_` in + // `dragEnd_`. + dragElement.classList.add('dropped'); + + this.tileElements_.forEach(el => resetTilePosition(el)); + resetTilePosition(this.$.addShortcut); } } @@ -674,19 +716,21 @@ } this.dragStart_(e.target as HTMLElement, e.x, e.y); + const dragOver = (e: DragEvent) => { e.preventDefault(); e.dataTransfer!.dropEffect = 'move'; this.dragOver_(e.x, e.y); }; - this.ownerDocument.addEventListener('dragover', dragOver); - this.ownerDocument.addEventListener('dragend', e => { - this.ownerDocument.removeEventListener('dragover', dragOver); - this.dragEnd_(e.x, e.y); + + const drop = (e: DragEvent) => { + this.drop_(e.x, e.y); + const dropIndex = getHitIndex(this.tileRects_, e.x, e.y); if (dropIndex !== -1) { this.enableForceHover_(dropIndex); } + this.addEventListener('pointermove', () => { this.clearForceHover_(); // When |reordering_| is true, the normal hover style is not shown. @@ -694,6 +738,14 @@ // after the mouse moves. this.reordering_ = false; }, {once: true}); + }; + + this.ownerDocument.addEventListener('dragover', dragOver); + this.ownerDocument.addEventListener('drop', drop); + this.ownerDocument.addEventListener('dragend', _ => { + this.ownerDocument.removeEventListener('dragover', dragOver); + this.ownerDocument.removeEventListener('drop', drop); + this.dragEnd_(); }, {once: true}); } @@ -857,7 +909,8 @@ tileElement.removeEventListener('touchend', touchEnd); tileElement.removeEventListener('touchcancel', touchEnd); const {clientX, clientY} = e.changedTouches[0]; - this.dragEnd_(clientX, clientY); + this.drop_(clientX, clientY); + this.dragEnd_(); this.reordering_ = false; }; this.ownerDocument.addEventListener('touchmove', touchMove);
diff --git a/url/url_canon.h b/url/url_canon.h index 71343b8..8c48f98 100644 --- a/url/url_canon.h +++ b/url/url_canon.h
@@ -699,7 +699,6 @@ // Use for standard URLs with authorities and paths. COMPONENT_EXPORT(URL) bool CanonicalizeStandardURL(const char* spec, - int spec_len, const Parsed& parsed, SchemeType scheme_type, CharsetConverter* query_converter, @@ -707,7 +706,6 @@ Parsed* new_parsed); COMPONENT_EXPORT(URL) bool CanonicalizeStandardURL(const char16_t* spec, - int spec_len, const Parsed& parsed, SchemeType scheme_type, CharsetConverter* query_converter, @@ -749,14 +747,12 @@ // Use for filesystem URLs. COMPONENT_EXPORT(URL) bool CanonicalizeFileSystemURL(const char* spec, - int spec_len, const Parsed& parsed, CharsetConverter* query_converter, CanonOutput* output, Parsed* new_parsed); COMPONENT_EXPORT(URL) bool CanonicalizeFileSystemURL(const char16_t* spec, - int spec_len, const Parsed& parsed, CharsetConverter* query_converter, CanonOutput* output,
diff --git a/url/url_canon_filesystemurl.cc b/url/url_canon_filesystemurl.cc index f1a9f1c..2510005 100644 --- a/url/url_canon_filesystemurl.cc +++ b/url/url_canon_filesystemurl.cc
@@ -17,7 +17,7 @@ // We use the URLComponentSource for the outer URL, as it can have replacements, // whereas the inner_url can't, so it uses spec. -template<typename CHAR, typename UCHAR> +template <typename CHAR> bool DoCanonicalizeFileSystemURL(const CHAR* spec, const URLComponentSource<CHAR>& source, const Parsed& parsed, @@ -56,9 +56,9 @@ // Strip out the user information from the inner URL, if any. inner_scheme_type = SCHEME_WITH_HOST_AND_PORT; } - success = CanonicalizeStandardURL( - spec, inner_parsed->Length(), *inner_parsed, inner_scheme_type, - charset_converter, output, &new_inner_parsed); + success = + CanonicalizeStandardURL(spec, *inner_parsed, inner_scheme_type, + charset_converter, output, &new_inner_parsed); } else { // TODO(ericu): The URL is wrong, but should we try to output more of what // we were given? Echoing back filesystem:mailto etc. doesn't seem all that @@ -84,25 +84,21 @@ } // namespace bool CanonicalizeFileSystemURL(const char* spec, - int spec_len, const Parsed& parsed, CharsetConverter* charset_converter, CanonOutput* output, Parsed* new_parsed) { - return DoCanonicalizeFileSystemURL<char, unsigned char>( - spec, URLComponentSource<char>(spec), parsed, charset_converter, output, - new_parsed); + return DoCanonicalizeFileSystemURL(spec, URLComponentSource(spec), parsed, + charset_converter, output, new_parsed); } bool CanonicalizeFileSystemURL(const char16_t* spec, - int spec_len, const Parsed& parsed, CharsetConverter* charset_converter, CanonOutput* output, Parsed* new_parsed) { - return DoCanonicalizeFileSystemURL<char16_t, char16_t>( - spec, URLComponentSource<char16_t>(spec), parsed, charset_converter, - output, new_parsed); + return DoCanonicalizeFileSystemURL(spec, URLComponentSource(spec), parsed, + charset_converter, output, new_parsed); } bool ReplaceFileSystemURL(const char* base, @@ -114,8 +110,8 @@ URLComponentSource<char> source(base); Parsed parsed(base_parsed); SetupOverrideComponents(base, replacements, &source, &parsed); - return DoCanonicalizeFileSystemURL<char, unsigned char>( - base, source, parsed, charset_converter, output, new_parsed); + return DoCanonicalizeFileSystemURL(base, source, parsed, charset_converter, + output, new_parsed); } bool ReplaceFileSystemURL(const char* base, @@ -128,8 +124,8 @@ URLComponentSource<char> source(base); Parsed parsed(base_parsed); SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed); - return DoCanonicalizeFileSystemURL<char, unsigned char>( - base, source, parsed, charset_converter, output, new_parsed); + return DoCanonicalizeFileSystemURL(base, source, parsed, charset_converter, + output, new_parsed); } } // namespace url
diff --git a/url/url_canon_stdurl.cc b/url/url_canon_stdurl.cc index 304ca4c0..3afc9d8 100644 --- a/url/url_canon_stdurl.cc +++ b/url/url_canon_stdurl.cc
@@ -13,7 +13,7 @@ namespace { -template <typename CHAR, typename UCHAR> +template <typename CHAR> bool DoCanonicalizeStandardURL(const URLComponentSource<CHAR>& source, const Parsed& parsed, SchemeType scheme_type, @@ -145,27 +145,25 @@ } bool CanonicalizeStandardURL(const char* spec, - int spec_len, const Parsed& parsed, SchemeType scheme_type, CharsetConverter* query_converter, CanonOutput* output, Parsed* new_parsed) { - return DoCanonicalizeStandardURL<char, unsigned char>( - URLComponentSource<char>(spec), parsed, scheme_type, query_converter, - output, new_parsed); + return DoCanonicalizeStandardURL(URLComponentSource(spec), parsed, + scheme_type, query_converter, output, + new_parsed); } bool CanonicalizeStandardURL(const char16_t* spec, - int spec_len, const Parsed& parsed, SchemeType scheme_type, CharsetConverter* query_converter, CanonOutput* output, Parsed* new_parsed) { - return DoCanonicalizeStandardURL<char16_t, char16_t>( - URLComponentSource<char16_t>(spec), parsed, scheme_type, query_converter, - output, new_parsed); + return DoCanonicalizeStandardURL(URLComponentSource(spec), parsed, + scheme_type, query_converter, output, + new_parsed); } // It might be nice in the future to optimize this so unchanged components don't @@ -187,8 +185,8 @@ URLComponentSource<char> source(base); Parsed parsed(base_parsed); SetupOverrideComponents(base, replacements, &source, &parsed); - return DoCanonicalizeStandardURL<char, unsigned char>( - source, parsed, scheme_type, query_converter, output, new_parsed); + return DoCanonicalizeStandardURL(source, parsed, scheme_type, query_converter, + output, new_parsed); } // For 16-bit replacements, we turn all the replacements into UTF-8 so the @@ -204,8 +202,8 @@ URLComponentSource<char> source(base); Parsed parsed(base_parsed); SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed); - return DoCanonicalizeStandardURL<char, unsigned char>( - source, parsed, scheme_type, query_converter, output, new_parsed); + return DoCanonicalizeStandardURL(source, parsed, scheme_type, query_converter, + output, new_parsed); } } // namespace url
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc index fd10ca0..edf664401 100644 --- a/url/url_canon_unittest.cc +++ b/url/url_canon_unittest.cc
@@ -1769,8 +1769,8 @@ std::string out_str; StdStringCanonOutput output(&out_str); bool success = CanonicalizeStandardURL( - i.input, url_len, parsed, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, - nullptr, &output, &out_parsed); + i.input, parsed, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, + &output, &out_parsed); output.Complete(); EXPECT_EQ(i.expected_success, success); @@ -2342,8 +2342,8 @@ Parsed out_parsed; std::string out_str; StdStringCanonOutput output(&out_str); - bool success = CanonicalizeFileSystemURL(i.input, url_len, parsed, nullptr, - &output, &out_parsed); + bool success = CanonicalizeFileSystemURL(i.input, parsed, nullptr, &output, + &out_parsed); output.Complete(); EXPECT_EQ(i.expected_success, success);
diff --git a/url/url_parse_perftest.cc b/url/url_parse_perftest.cc index f06e019..317f1a78 100644 --- a/url/url_parse_perftest.cc +++ b/url/url_parse_perftest.cc
@@ -66,21 +66,21 @@ url::ParseStandardURL(kTypicalUrl1.data(), kTypicalUrl1.size(), &parsed1); output.set_length(0); url::CanonicalizeStandardURL( - kTypicalUrl1.data(), kTypicalUrl1.size(), parsed1, + kTypicalUrl1.data(), parsed1, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &output, &out_parsed); url::ParseStandardURL(kTypicalUrl2.data(), kTypicalUrl2.size(), &parsed2); output.set_length(0); url::CanonicalizeStandardURL( - kTypicalUrl2.data(), kTypicalUrl2.size(), parsed2, + kTypicalUrl2.data(), parsed2, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &output, &out_parsed); url::ParseStandardURL(kTypicalUrl3.data(), kTypicalUrl3.size(), &parsed3); output.set_length(0); url::CanonicalizeStandardURL( - kTypicalUrl3.data(), kTypicalUrl3.size(), parsed3, + kTypicalUrl3.data(), parsed3, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &output, &out_parsed); } @@ -100,7 +100,7 @@ std::string out1; url::StdStringCanonOutput output1(&out1); url::CanonicalizeStandardURL( - kTypicalUrl1.data(), kTypicalUrl1.size(), parsed1, + kTypicalUrl1.data(), parsed1, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &output1, &out_parsed); @@ -108,7 +108,7 @@ std::string out2; url::StdStringCanonOutput output2(&out2); url::CanonicalizeStandardURL( - kTypicalUrl2.data(), kTypicalUrl2.size(), parsed2, + kTypicalUrl2.data(), parsed2, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &output2, &out_parsed); @@ -116,7 +116,7 @@ std::string out3; url::StdStringCanonOutput output3(&out3); url::CanonicalizeStandardURL( - kTypicalUrl3.data(), kTypicalUrl3.size(), parsed3, + kTypicalUrl3.data(), parsed3, url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION, nullptr, &output3, &out_parsed); }
diff --git a/url/url_util.cc b/url/url_util.cc index 9258cfc..6f83f33 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -273,14 +273,13 @@ } else if (DoCompareSchemeComponent(spec, scheme, url::kFileSystemScheme)) { // Filesystem URLs are special. ParseFileSystemURL(spec, spec_len, &parsed_input); - success = CanonicalizeFileSystemURL(spec, spec_len, parsed_input, - charset_converter, output, - output_parsed); + success = CanonicalizeFileSystemURL(spec, parsed_input, charset_converter, + output, output_parsed); } else if (DoIsStandard(spec, scheme, &scheme_type)) { // All "normal" URLs. ParseStandardURL(spec, spec_len, &parsed_input); - success = CanonicalizeStandardURL(spec, spec_len, parsed_input, scheme_type, + success = CanonicalizeStandardURL(spec, parsed_input, scheme_type, charset_converter, output, output_parsed); } else if (DoCompareSchemeComponent(spec, scheme, url::kMailToScheme)) {
diff --git a/v8 b/v8 index b057218..13b0f9f 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit b057218023961f8b94b0313dd6ddbcc274c06e74 +Subproject commit 13b0f9f24b88983f07952beb652e1bce97a4deb6