diff --git a/DEPS b/DEPS index 05a3c855..e5a5fdc 100644 --- a/DEPS +++ b/DEPS
@@ -275,15 +275,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': 'd05aff78a0ed8b745fc14f390c6c06b9a2cb2a03', + 'skia_revision': 'fb2d7d7a5975cc8cc74086f1b2ed910cfcd2b309', # 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': 'ba785873c41d2bd9d1788ee225f6a405dd638a3d', + 'v8_revision': '747cd3ae5d474f09cba2498949a53b948f8754a3', # 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': '9ea3967d3e8b97b7d70d193560ef388d953421ce', + 'angle_revision': 'a2fe4445dce56d79ef06e4bc8f3f70e3c20e8bea', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -302,7 +302,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:8.20220529.2.1', + 'fuchsia_version': 'version:8.20220530.1.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -334,7 +334,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. - 'harfbuzz_revision': 'acdab17ed3507bc9524cb57bef703a983e1031cf', + 'harfbuzz_revision': 'd61b2074915cf5f8044dcb8e3dafc04b5b58c6b8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Emoji Segmenter # and whatever else without interference from each other. @@ -354,7 +354,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': '54f6ed90dab6ad21bb3f751d3ad04ce7411fc27a', + 'devtools_frontend_revision': '4f8eb95593e80f31965ac653171f386db31cfc55', # 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. @@ -390,11 +390,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'b8ac93390909e0a87a838b71f431f01c66191292', + 'dawn_revision': 'aa25d7ed2bfb2767ccbfd411e0b521d166b286b8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '97921ca5e18bd2348728283aa78d67b12af8f76f', + 'quiche_revision': '66cfacd105f168803bfc75dd99f2555d0e6bbe5c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -1533,7 +1533,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '6214d0c954d720a3c87cf7673903d679d2ae7413', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '23339a6fac0aeb6c2289af885ee4d1df0a9aaf90', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1708,7 +1708,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '70091fdb8d3d037b8f2919eb63e5a2bf6444deb7', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e4374a6020e6568fec7943dba811e5f37289a7ca', + Var('webrtc_git') + '/src.git' + '@' + 'fc2c24ef4406484a2e6bec4d7aa44a2c78e6cdd0', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1781,7 +1781,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9d25e6fc918ffb282fd4ad0e4c874259cae3f267', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3c3d2fcd96d1b03badcfb56aa17cc46455b40ecf', 'condition': 'checkout_src_internal', }, @@ -1800,7 +1800,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/eche_app/app', - 'version': 'TtVR9w4q1StI4bDWt2rovosY0257oWZl9HZ_IuCX7DQC', + 'version': 'PsOW8S_6c5amu3xQkVNmX06QA-OglSYYV0iTBY-a2UsC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1833,7 +1833,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'GYuCX6QFNlK9d1YCFyf2SMAKXA874T5KYJDiixmka7sC', + 'version': '2WQHIccAp2RigVJJDLtugL6zbmz1Y7UcNCmsFLrVecMC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc index 0f4f4cda..c09a4b8 100644 --- a/android_webview/common/aw_features.cc +++ b/android_webview/common/aw_features.cc
@@ -14,7 +14,7 @@ // Enables package name logging for the most popular WebView embedders that are // on a dynamically generated allowlist. const base::Feature kWebViewAppsPackageNamesAllowlist{ - "WebViewAppsPackageNamesAllowlist", base::FEATURE_DISABLED_BY_DEFAULT}; + "WebViewAppsPackageNamesAllowlist", base::FEATURE_ENABLED_BY_DEFAULT}; // Maximum time to throttle querying the app package names allowlist from the // component updater service, used when there is a valid cached allowlist
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index c5bb0aa..7abd0bb 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1435,6 +1435,10 @@ const base::Feature kTerminalDev{"TerminalDev", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables multi-profile theme support for Terminal.. +const base::Feature kTerminalMultiProfile{"TerminalMultiProfile", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables tmux integration in the Terminal System App. const base::Feature kTerminalTmuxIntegration{"TerminalTmuxIntegration", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 89ae419..fe738c5 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -564,6 +564,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kTelemetryExtension; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kTerminalDev; COMPONENT_EXPORT(ASH_CONSTANTS) +extern const base::Feature kTerminalMultiProfile; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kTerminalTmuxIntegration; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kTrafficCountersEnabled;
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index 9b777f31..9389f09 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -250,6 +250,10 @@ const char kAshUiModeClamshell[] = "clamshell"; const char kAshUiModeTablet[] = "touch_view"; +// Makes ash use ChromeOS mojo service manager as the mojo broker. +const char kAshUseCrOSMojoServiceManager[] = + "ash-use-cros-mojo-service-manager"; + // (Most) Chrome OS hardware reports ACPI power button releases correctly. // Standard hardware reports releases immediately after presses. If set, we // lock the screen or shutdown the system immediately in response to a press
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index 9bb10502..8604d5a9 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -82,6 +82,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAshUiMode[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAshUiModeClamshell[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAshUiModeTablet[]; +COMPONENT_EXPORT(ASH_CONSTANTS) +extern const char kAshUseCrOSMojoServiceManager[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAuraLegacyPowerButton[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kCellularFirst[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kChildWallpaperLarge[];
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc index 937d7e0..cb78030 100644 --- a/ash/system/message_center/ash_notification_view.cc +++ b/ash/system/message_center/ash_notification_view.cc
@@ -735,6 +735,7 @@ void AshNotificationView::AddGroupNotification( const message_center::Notification& notification) { + DCHECK(is_grouped_parent_view_); // Do not add a grouped notification if a view for it already exists. if (FindGroupNotificationView(notification.id())) return; @@ -747,6 +748,8 @@ notification_view->set_scroller( scroller() ? scroller() : grouped_notifications_scroll_view_); + header_row()->SetTimestamp(notification.timestamp()); + grouped_notifications_container_->AddChildViewAt(std::move(notification_view), 0); @@ -759,6 +762,7 @@ void AshNotificationView::PopulateGroupNotifications( const std::vector<const message_center::Notification*>& notifications) { + DCHECK(is_grouped_parent_view_); // Clear all grouped notifications since we will add all grouped notifications // from scratch. total_grouped_notifications_ = 0; @@ -768,6 +772,10 @@ auto notification_view = std::make_unique<AshNotificationView>(*notification, /*shown_in_popup=*/false); + + if (!total_grouped_notifications_) + header_row()->SetTimestamp(notification->timestamp()); + notification_view->SetVisible( total_grouped_notifications_ < message_center_style::kMaxGroupedNotificationsInCollapsedState || @@ -808,8 +816,6 @@ self->grouped_notifications_container_->RemoveChildViewT(to_be_deleted); self->total_grouped_notifications_--; - self->left_content_->SetVisible(self->total_grouped_notifications_ == - 0); self->expand_button_->UpdateGroupedNotificationsCount( self->total_grouped_notifications_); @@ -845,6 +851,7 @@ !is_grouped_child_view_ && !is_grouped_parent_view_ && expanded; header_row()->SetVisible(is_grouped_parent_view_ || (is_single_expanded_notification)); + header_row()->SetTimestampVisible(!is_grouped_parent_view_ || !expanded); if (title_row_) { title_row_->UpdateVisibility(is_grouped_child_view_ ||
diff --git a/ash/system/message_center/ash_notification_view_unittest.cc b/ash/system/message_center/ash_notification_view_unittest.cc index ccfef43..890b81a 100644 --- a/ash/system/message_center/ash_notification_view_unittest.cc +++ b/ash/system/message_center/ash_notification_view_unittest.cc
@@ -257,6 +257,10 @@ views::Label* GetTimestampInCollapsedView(AshNotificationView* view) { return view->title_row_->timestamp_in_collapsed_view_; } + const views::Label* GetTimestamp(AshNotificationView* view) { + return view->header_row()->timestamp_view_for_testing(); + } + views::Label* GetMessageLabel(AshNotificationView* view) { return view->message_label(); } @@ -481,13 +485,14 @@ auto* child_view = GetFirstGroupedChildNotificationView(notification_view()); EXPECT_TRUE(GetCollapsedSummaryView(child_view)->GetVisible()); EXPECT_FALSE(GetMainView(child_view)->GetVisible()); - - // Expanding the parent notification should make the counter invisible and - // the child notifications should now have the main view visible instead of - // the summary. + EXPECT_TRUE(GetTimestamp(notification_view())->GetVisible()); + // Expanding the parent notification should make the expand button counter and + // timestamp invisible and the child notifications should now have the main + // view visible instead of the summary. notification_view()->SetExpanded(true); EXPECT_FALSE( GetExpandButton(notification_view())->label_for_test()->GetVisible()); + EXPECT_FALSE(GetTimestamp(notification_view())->GetVisible()); EXPECT_FALSE(GetCollapsedSummaryView(child_view)->GetVisible()); EXPECT_TRUE(GetMainView(child_view)->GetVisible()); } @@ -583,19 +588,6 @@ EXPECT_TRUE(GetExpandButton(notification_view())->GetVisible()); } -TEST_F(AshNotificationViewTest, LeftContentNotVisibleInGroupedNotifications) { - auto notification = CreateTestNotification(); - - EXPECT_TRUE(GetLeftContent(notification_view())->GetVisible()); - - auto group_child = CreateTestNotification(); - notification_view()->AddGroupNotification(*group_child.get()); - EXPECT_FALSE(GetLeftContent(notification_view())->GetVisible()); - - notification_view()->RemoveGroupNotification(group_child->id()); - EXPECT_TRUE(GetLeftContent(notification_view())->GetVisible()); -} - TEST_F(AshNotificationViewTest, WarningLevelInSummaryText) { auto notification = CreateTestNotification(); notification_view()->UpdateWithNotification(*notification);
diff --git a/ash/webui/camera_app_ui/resources/css/button.css b/ash/webui/camera_app_ui/resources/css/button.css index d51f751..31942bb5 100644 --- a/ash/webui/camera_app_ui/resources/css/button.css +++ b/ash/webui/camera_app_ui/resources/css/button.css
@@ -14,8 +14,7 @@ } button.text-button.pill:focus { - --focus-ring-size: 2px; - --focus-ring-style: pill; + outline-offset: 2px; } .text-button.pill { @@ -48,8 +47,7 @@ } button.icon-button:focus { - --focus-ring-size: 2px; - --focus-ring-style: circle; + outline-offset: 2px; } button.icon-button.dark:hover {
diff --git a/ash/webui/camera_app_ui/resources/css/css.gni b/ash/webui/camera_app_ui/resources/css/css.gni index bdcea2d..5bc601e 100644 --- a/ash/webui/camera_app_ui/resources/css/css.gni +++ b/ash/webui/camera_app_ui/resources/css/css.gni
@@ -6,7 +6,6 @@ "button.css", "document_mode_dialog.css", "flash.css", - "focus_ring.css", "inkdrop.css", "main.css", "mode/mode.css",
diff --git a/ash/webui/camera_app_ui/resources/css/focus_ring.css b/ash/webui/camera_app_ui/resources/css/focus_ring.css deleted file mode 100644 index 1b7ec5a0..0000000 --- a/ash/webui/camera_app_ui/resources/css/focus_ring.css +++ /dev/null
@@ -1,53 +0,0 @@ -/* Copyright 2021 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -body:not(.show-focus-ring) #focus-ring { - visibility: hidden; -} - -@property --focus-ring-size { - syntax: '<length>'; - inherits: true; - initial-value: 3px; -} - -@property --focus-ring-style { - syntax: '*'; - inherits: true; - initial-value: default; -} - -button, -input { - --focus-ring-size: 3px; -} - -.circle :is(button, input) { - --focus-ring-style: circle; -} - -#focus-ring { - border: 2px solid var(--blue-300); - border-radius: 4px; - height: 0; /* Calculate at runtime. */ - left: 0; /* Calculate at runtime. */ - pointer-events: none; - position: absolute; - top: 0; /* Calculate at runtime. */ - transform: translate(-50%, -50%); - width: 0; /* Calculate at runtime. */ - z-index: 99; -} - -#focus-ring.circle { - border-radius: 50%; -} - -#focus-ring.pill { - border-radius: var(--border-radius-rounded-with-short-side); -} - -#focus-ring.none { - display: none; -}
diff --git a/ash/webui/camera_app_ui/resources/css/main.css b/ash/webui/camera_app_ui/resources/css/main.css index 471e505c..c5e2090 100644 --- a/ash/webui/camera_app_ui/resources/css/main.css +++ b/ash/webui/camera_app_ui/resources/css/main.css
@@ -121,6 +121,13 @@ width: 40px; } +.menu-item > input.icon { + outline-offset: -4px; +} +input[type=radio].icon { + border-radius: 50%; +} + ::-webkit-scrollbar { height: 0; width: 0; @@ -246,6 +253,7 @@ #modes-group { display: block; overflow: auto; + padding: 10px 0; pointer-events: auto; text-align: center; user-select: none; @@ -281,9 +289,6 @@ } #modes-group .mode-item { - --focus-ring-gap: 7px; - --focus-ring-border: 2px; - display: inline-block; font-size: 0; /* Remove space between inline-block. */ margin: 0 8px; @@ -307,6 +312,10 @@ transform: none; } +div.mode-item>input { + border-radius: 16px/50%; +} + div.mode-item>span { border-radius: 16px/50%; color: white; @@ -320,10 +329,8 @@ } .mode-item>input { - --focus-ring-size: 7px; - --focus-ring-style: mode-item-input; - height: 100%; + outline-offset: 7px; position: absolute; width: 100%; z-index: 1; @@ -336,15 +343,10 @@ text-shadow: none; } -#focus-ring.mode-item-input { - border-radius: 23px/50%; -} - button.shutter { - --focus-ring-size: 9px; - display: none; height: 60px; + outline-offset: 9px; width: 60px; z-index: 1; /* On top of transforming switch-mode buttons. */ } @@ -544,10 +546,9 @@ } #switch-device { - --focus-ring-size: 8px; - background-image: url(/images/camera_button_switch_device.svg); height: var(--big-icon); + outline-offset: 8px; width: var(--big-icon); } @@ -1220,14 +1221,13 @@ } button.menu-item { - --focus-ring-size: -3px; + outline-offset: -3px; } .menu-header button.icon { /* Icon image is small enough and won't be covered by -1px */ - --focus-ring-size: -1px; - background-image: url(/images/settings_button_back.svg); + outline-offset: -1px; } html[dir=rtl] .menu-header .icon { @@ -1492,3 +1492,16 @@ #view-video-resolution-settings .fps-60.checked { background-image: url(/images/camera_button_fps_60_checked.svg); } + +[tabindex='0'] { + outline: none; + outline-offset: 3px; +} + +[tabindex='0']:focus-visible { + outline: 2px solid var(--blue-300); +} + +.circle :is(button, input) { + border-radius: 50%; +}
diff --git a/ash/webui/camera_app_ui/resources/css/mode/mode.css b/ash/webui/camera_app_ui/resources/css/mode/mode.css index 35dbb02..34935c6 100644 --- a/ash/webui/camera_app_ui/resources/css/mode/mode.css +++ b/ash/webui/camera_app_ui/resources/css/mode/mode.css
@@ -27,6 +27,10 @@ z-index: 1; } +.mode-subgroup > .item > input[type=radio] { + border-radius: var(--border-radius-rounded-with-short-side); +} + .mode-subgroup > .item > div.label { border-radius: var(--border-radius-rounded-with-short-side); font: 500 14px/20px var(--default-font-family);
diff --git a/ash/webui/camera_app_ui/resources/css/mode/scan.css b/ash/webui/camera_app_ui/resources/css/mode/scan.css index 4b1025a..bc269ecc 100644 --- a/ash/webui/camera_app_ui/resources/css/mode/scan.css +++ b/ash/webui/camera_app_ui/resources/css/mode/scan.css
@@ -354,7 +354,6 @@ #view-crop-document .review-image .dot { --icon-size: 12px; - --focus-ring-style: none; --focus-size: 32px; border-radius: 50%; @@ -365,6 +364,10 @@ width: 48px; } +#view-crop-document .review-image .dot:focus-visible { + outline: none; +} + #view-crop-document .review-image .dot::before, #view-crop-document .review-image .dot::after { border-radius: 50%;
diff --git a/ash/webui/camera_app_ui/resources/css/ptz_panel.css b/ash/webui/camera_app_ui/resources/css/ptz_panel.css index 10bdd043..bbbf5256 100644 --- a/ash/webui/camera_app_ui/resources/css/ptz_panel.css +++ b/ash/webui/camera_app_ui/resources/css/ptz_panel.css
@@ -17,6 +17,11 @@ border-radius: var(--border-radius-rounded-with-short-side); height: 32px; margin-bottom: 8px; + overflow: unset; +} + +#reset-all-container>button { + border-radius: var(--border-radius-rounded-with-short-side); } #ptz-reset-all { @@ -54,8 +59,6 @@ #ptz-panel-container button { --svg-width: 20px; --svg-height: 20px; - --focus-ring-size: 8px; - --focus-ring-style: circle; height: 48px; position: absolute; @@ -66,6 +69,16 @@ opacity: 0.38; } +#ptz-panel-container>button:focus { + outline: none; +} + +#ptz-panel-container>button:focus-visible::before { + border-radius: 50%; + outline: 2px solid var(--blue-300); + outline-offset: 3px; +} + body:not(.has-pan-support) :is(#pan-left, #pan-right), body:not(.has-tilt-support) :is(#tilt-up, #tilt-down), body:not(.has-zoom-support) :is(#zoom-in, #zoom-out) { @@ -99,9 +112,11 @@ } #ptz-panel-container button::before { + height: var(--svg-height); left: calc(50% - var(--svg-width) / 2); position: absolute; top: calc(50% - var(--svg-height) / 2); + width: var(--svg-width); }
diff --git a/ash/webui/camera_app_ui/resources/js/device/preview.ts b/ash/webui/camera_app_ui/resources/js/device/preview.ts index 70181ef..f97c086 100644 --- a/ash/webui/camera_app_ui/resources/js/device/preview.ts +++ b/ash/webui/camera_app_ui/resources/js/device/preview.ts
@@ -38,7 +38,6 @@ } from '../type.js'; import * as util from '../util.js'; import {WaitableEvent} from '../waitable_event.js'; -import {windowController} from '../window_controller.js'; import { StreamConstraints, @@ -101,10 +100,6 @@ * @param onNewStreamNeeded Callback to request new stream. */ constructor(private readonly onNewStreamNeeded: () => Promise<void>) { - window.addEventListener('resize', () => this.onWindowStatusChanged()); - - windowController.addListener(() => this.onWindowStatusChanged()); - for (const s of [state.State.EXPERT, state.State.SHOW_METADATA]) { state.addObserver(s, () => this.updateShowMetadata()); } @@ -663,18 +658,11 @@ } /** - * Handles the the window state or window size changed. - */ - private onWindowStatusChanged() { - nav.onWindowStatusChanged(); - } - - /** * Handles changed intrinsic size (first loaded or orientation changes). */ private async onIntrinsicSizeChanged(): Promise<void> { - if (this.video.videoWidth && this.video.videoHeight) { - this.onWindowStatusChanged(); + if (this.video.videoWidth !== 0 && this.video.videoHeight !== 0) { + nav.layoutShownViews(); } this.cancelFocus(); }
diff --git a/ash/webui/camera_app_ui/resources/js/focus_ring.ts b/ash/webui/camera_app_ui/resources/js/focus_ring.ts deleted file mode 100644 index 60fe2328..0000000 --- a/ash/webui/camera_app_ui/resources/js/focus_ring.ts +++ /dev/null
@@ -1,122 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assert} from './assert.js'; -import {cssStyle} from './css.js'; -import * as dom from './dom.js'; -import * as state from './state.js'; -import {getStyleValueInPx} from './util.js'; - -/** - * Focus ring element. - */ -let ring: HTMLElement|null = null; - -let ringCSSStyle: CSSStyleDeclaration|null = null; - -/** - * All valid values of '--focus-ring-style'. - */ -const ringStyleValues = new Set(['circle', 'mode-item-input', 'none', 'pill']); - -/** - * The reference bounding rectangle of focused UI. - */ -let uiRect = new DOMRectReadOnly(); - -/** - * Name of event triggered for calculating bounding rectangle of focused UI. - */ -export const FOCUS_RING_UI_RECT_EVENT_NAME = 'focusringuirect'; - -/** - * Sets reference bounding rectangle of focused UI. - */ -export function setUIRect(rect: DOMRectReadOnly): void { - uiRect = rect; -} - -/** - * Shows focus ring on |el|. - */ -function showFocus(el: HTMLElement) { - assert(ring !== null); - assert(ringCSSStyle !== null); - const style = el.computedStyleMap(); - const size = getStyleValueInPx(style, '--focus-ring-size'); - const ringStyleValue = `${style.get('--focus-ring-style')}`; - for (const v of ringStyleValues) { - ring.classList.toggle(v, ringStyleValue.includes(v)); - } - const uiRectEvent = - new CustomEvent(FOCUS_RING_UI_RECT_EVENT_NAME, {cancelable: true}); - const doDefault = el.dispatchEvent(uiRectEvent); - if (doDefault) { - setUIRect(el.getBoundingClientRect()); - } - ringCSSStyle.setProperty('width', `${uiRect.width + size * 2}px`); - ringCSSStyle.setProperty('height', `${uiRect.height + size * 2}px`); - ringCSSStyle.setProperty('top', `${(uiRect.top + uiRect.bottom) / 2}px`); - ringCSSStyle.setProperty('left', `${(uiRect.left + uiRect.right) / 2}px`); -} - -function setup(el: HTMLElement): void { - el.addEventListener('focus', () => showFocus(el)); - if (el === document.activeElement) { - showFocus(el); - } -} - -/** - * Setup the focus listener for given nodes recursively. If a parent node is - * setup, no setup will be applied to its children nodes. - */ -function setupForNodes(nodes: NodeList): void { - for (const node of nodes) { - if (!(node instanceof HTMLElement)) { - continue; - } - if (node.hasAttribute('tabindex')) { - setup(node); - continue; - } - setupForNodes(node.childNodes); - } -} - -/** - * Check visibility of the focus ring. - */ -export function checkFocusRingVisibility(): void { - const showFocusRing = - document.activeElement?.hasAttribute('tabindex') === true && - state.get(state.State.KEYBOARD_NAVIGATION); - state.set(state.State.SHOW_FOCUS_RING, showFocusRing); -} - -/** - * Initializes DOM elements and observers used for focus ring. - */ -export function initialize(): void { - ring = dom.get('#focus-ring', HTMLElement); - ringCSSStyle = cssStyle('#focus-ring'); - - window.addEventListener('focus', checkFocusRingVisibility, true); - - for (const el of dom.getAll('[tabindex]', HTMLElement)) { - setup(el); - } - const observer = new MutationObserver((mutationList) => { - for (const mutation of mutationList) { - assert(mutation.type === 'childList'); - // Only the newly added nodes with [tabindex] are considered here. So - // simply adding class attribute on existing element will not work. - setupForNodes(mutation.addedNodes); - } - }); - observer.observe(document.body, { - subtree: true, - childList: true, - }); -}
diff --git a/ash/webui/camera_app_ui/resources/js/js.gni b/ash/webui/camera_app_ui/resources/js/js.gni index 84e35046..a61d829 100644 --- a/ash/webui/camera_app_ui/resources/js/js.gni +++ b/ash/webui/camera_app_ui/resources/js/js.gni
@@ -32,7 +32,6 @@ "expert.ts", "face.ts", "flag.ts", - "focus_ring.ts", "gallerybutton.ts", "geometry.ts", "h264.ts",
diff --git a/ash/webui/camera_app_ui/resources/js/main.ts b/ash/webui/camera_app_ui/resources/js/main.ts index 776519b..edf526b 100644 --- a/ash/webui/camera_app_ui/resources/js/main.ts +++ b/ash/webui/camera_app_ui/resources/js/main.ts
@@ -10,7 +10,6 @@ import {ModeConstraints} from './device/type.js'; import * as dom from './dom.js'; import {reportError} from './error.js'; -import * as focusRing from './focus_ring.js'; import {GalleryButton} from './gallerybutton.js'; import {I18nString} from './i18n_string.js'; import {Intent} from './intent.js'; @@ -42,6 +41,7 @@ import {View} from './views/view.js'; import {Warning, WarningType} from './views/warning.js'; import {WaitableEvent} from './waitable_event.js'; +import {windowController} from './window_controller.js'; /** * The app window instance which is used for communication with Tast tests. For @@ -107,11 +107,13 @@ } }, {passive: false, capture: true}); + window.addEventListener('resize', () => nav.layoutShownViews()); + windowController.addListener(() => nav.layoutShownViews()); + util.setupI18nElements(document.body); this.setupToggles(); localStorage.cleanup(); this.setupEffect(); - focusRing.initialize(); // Set up views navigation by their DOM z-order. nav.setup([
diff --git a/ash/webui/camera_app_ui/resources/js/nav.ts b/ash/webui/camera_app_ui/resources/js/nav.ts index 865fa4c..aa29806 100644 --- a/ash/webui/camera_app_ui/resources/js/nav.ts +++ b/ash/webui/camera_app_ui/resources/js/nav.ts
@@ -4,7 +4,6 @@ import {assert} from './assert.js'; import {toggleExpertMode} from './expert.js'; -import {checkFocusRingVisibility} from './focus_ring.js'; import * as state from './state.js'; import * as toast from './toast.js'; import {ViewName} from './type.js'; @@ -14,12 +13,12 @@ /** * All views stacked in ascending z-order (DOM order) for navigation, and only - * the topmost visible view is active (clickable/focusable). + * the topmost shown view is active (clickable/focusable). */ let allViews: View[] = []; /** - * Index of the current topmost visible view in the stacked views. + * Index of the current topmost shown view in the stacked views. */ let topmostIndex = -1; @@ -42,11 +41,9 @@ allViews = views.flatMap((v) => [...getRecursiveViews(v)]); document.addEventListener('pointerdown', () => { state.set(state.State.KEYBOARD_NAVIGATION, false); - checkFocusRingVisibility(); }); document.addEventListener('keydown', () => { state.set(state.State.KEYBOARD_NAVIGATION, true); - checkFocusRingVisibility(); }); } @@ -62,7 +59,7 @@ /** * Shows the view indexed in the stacked views and activates the view only if - * it becomes the topmost visible view. + * it becomes the topmost shown view. * * @param index Index of the view. * @return View shown. @@ -85,7 +82,7 @@ } /** - * Finds the next topmost visible view in the stacked views. + * Finds the next topmost shown view in the stacked views. * * @return Index of the view found; otherwise, -1. */ @@ -100,7 +97,7 @@ /** * Hides the view indexed in the stacked views and deactivate the view if it was - * the topmost visible view. + * the topmost shown view. * * @param index Index of the view. */ @@ -148,11 +145,10 @@ * * @param name View name. * @param condition Optional condition for leaving the view. - * @return Whether successfully leaving the view or not. */ -export function close(name: ViewName, condition?: unknown): boolean { +export function close(name: ViewName, condition?: unknown): void { const index = findIndex(name); - return allViews[index].leave({kind: 'CLOSED', val: condition}); + allViews[index].leave({kind: 'CLOSED', val: condition}); } /** @@ -187,7 +183,7 @@ toggleExpertMode(); break; default: - // Make the topmost visible view handle the pressed key. + // Make the topmost shown view handle the pressed key. if (topmostIndex >= 0 && allViews[topmostIndex].onKeyPressed(key)) { event.preventDefault(); } @@ -195,11 +191,12 @@ } /** - * Handles when the window state or size changed. + * Relayout all shown views. + * + * All shown views need being relayout after window is resized or state + * changed. */ -export function onWindowStatusChanged(): void { - // All visible views need being relayout after window is resized or state - // changed. +export function layoutShownViews(): void { for (let i = allViews.length - 1; i >= 0; i--) { if (isShown(i)) { allViews[i].layout();
diff --git a/ash/webui/camera_app_ui/resources/js/state.ts b/ash/webui/camera_app_ui/resources/js/state.ts index 55b5e6e..f0c1abd8 100644 --- a/ash/webui/camera_app_ui/resources/js/state.ts +++ b/ash/webui/camera_app_ui/resources/js/state.ts
@@ -56,7 +56,6 @@ SAVE_METADATA = 'save-metadata', SHOULD_HANDLE_INTENT_RESULT = 'should-handle-intent-result', SHOW_ALL_RESOLUTIONS = 'show-all-resolutions', - SHOW_FOCUS_RING = 'show-focus-ring', SHOW_GIF_RECORDING_OPTION = 'show-gif-recording-option', SHOW_METADATA = 'show-metadata', SHOW_SCAN_MODE = 'show-scan-mode',
diff --git a/ash/webui/camera_app_ui/resources/js/views/ptz_panel.ts b/ash/webui/camera_app_ui/resources/js/views/ptz_panel.ts index 0ca68804..2c177b5d 100644 --- a/ash/webui/camera_app_ui/resources/js/views/ptz_panel.ts +++ b/ash/webui/camera_app_ui/resources/js/views/ptz_panel.ts
@@ -5,7 +5,6 @@ import {assert, assertExists, assertInstanceof} from '../assert.js'; import {ClearableAsyncJobQueue} from '../async_job_queue.js'; import * as dom from '../dom.js'; -import * as focusRing from '../focus_ring.js'; import * as metrics from '../metrics.js'; import * as nav from '../nav.js'; import * as state from '../state.js'; @@ -147,29 +146,6 @@ ViewName.PTZ_PANEL, {dismissByEsc: true, dismissByBackgroundClick: true}); - for (const el - of [this.panLeft, this.panRight, this.tiltUp, this.tiltDown, - this.zoomIn, this.zoomOut]) { - el.addEventListener(focusRing.FOCUS_RING_UI_RECT_EVENT_NAME, (evt) => { - if (!(state.get(state.State.HAS_PAN_SUPPORT) && - state.get(state.State.HAS_TILT_SUPPORT) && - state.get(state.State.HAS_ZOOM_SUPPORT))) { - return; - } - const style = getComputedStyle(el, '::before'); - function getStyleValue(attr: string) { - const px = style.getPropertyValue(attr); - return Number(px.replace(/^([\d.]+)px$/, '$1')); - } - const pRect = el.getBoundingClientRect(); - focusRing.setUIRect(new DOMRectReadOnly( - /* x */ pRect.left + getStyleValue('left'), - /* y */ pRect.top + getStyleValue('top'), getStyleValue('width'), - getStyleValue('height'))); - evt.preventDefault(); - }); - } - state.addObserver(state.State.STREAMING, (streaming) => { if (!streaming && state.get(this.name)) { nav.close(this.name);
diff --git a/ash/webui/camera_app_ui/resources/js/views/view.ts b/ash/webui/camera_app_ui/resources/js/views/view.ts index 5d84a6b..770ebe0 100644 --- a/ash/webui/camera_app_ui/resources/js/views/view.ts +++ b/ash/webui/camera_app_ui/resources/js/views/view.ts
@@ -311,14 +311,11 @@ * * @param condition Optional condition for leaving the view and also as * the result for the ended session. - * @return Whether able to leaving the view or not. */ - leave(condition: LeaveCondition = {kind: 'CLOSED'}): boolean { + leave(condition: LeaveCondition = {kind: 'CLOSED'}): void { if (this.session !== null && this.leaving(condition)) { this.session.signal(condition); this.session = null; - return true; } - return false; } }
diff --git a/ash/webui/camera_app_ui/resources/js/window_controller.ts b/ash/webui/camera_app_ui/resources/js/window_controller.ts index eb22763..f125be8 100644 --- a/ash/webui/camera_app_ui/resources/js/window_controller.ts +++ b/ash/webui/camera_app_ui/resources/js/window_controller.ts
@@ -112,7 +112,7 @@ } /** - * Adds listener for the window state (including window size) changed events. + * Adds listener for the window state changed events. */ addListener(listener: WindowStateChangedEventListener): void { this.listeners.add(listener);
diff --git a/ash/webui/camera_app_ui/resources/views/main.html b/ash/webui/camera_app_ui/resources/views/main.html index 2a1aac0..cb1dbbf 100644 --- a/ash/webui/camera_app_ui/resources/views/main.html +++ b/ash/webui/camera_app_ui/resources/views/main.html
@@ -11,7 +11,6 @@ <link rel="stylesheet" href="/css/button.css"> <link rel="stylesheet" href="/css/document_mode_dialog.css"> <link rel="stylesheet" href="/css/flash.css"> - <link rel="stylesheet" href="/css/focus_ring.css"> <link rel="stylesheet" href="/css/inkdrop.css"> <link rel="stylesheet" href="/css/mode/mode.css"> <link rel="stylesheet" href="/css/mode/scan.css"> @@ -509,7 +508,6 @@ aria-live="polite"></div> <div id="spoken_msg" class="centered-overlay" tabindex="-1" aria-live="polite"></div> - <div id="focus-ring"></div> <div id="tooltip" aria-hidden="true"></div> <audio id="sound-tick-final" src="/sounds/tick_final.ogg"></audio> <audio id="sound-tick-inc" src="/sounds/tick_inc.ogg"></audio>
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index d2ad884..dfd7e5b 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -8.20220529.1.1 +8.20220530.1.1
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index b1c9b0c7e7..6c60156 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1383,6 +1383,7 @@ "//chrome/gpu", "//chrome/renderer", "//chrome/utility", + "//components/about_ui", "//components/gwp_asan/buildflags", "//components/heap_profiling/in_process", "//components/power_scheduler",
diff --git a/chrome/VERSION b/chrome/VERSION index 148b1fd..2cc68b1 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=104 MINOR=0 -BUILD=5092 +BUILD=5093 PATCH=0
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java index 5eacefb..ed0b114 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataIntegrationTest.java
@@ -146,25 +146,18 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1274144") public void testEnterPayment() throws Exception { String profileId = mHelper.addDummyProfile("John Doe", "johndoe@gmail.com"); mHelper.addDummyCreditCard(profileId); ArrayList<ActionProto> list = new ArrayList<>(); - list.add( - ActionProto.newBuilder() - .setCollectUserData(CollectUserDataProto.newBuilder() - .setRequestPaymentMethod(true) - .setBillingAddressName("billing_address") - .addSupportedBasicCardNetworks("visa") - .setPrivacyNoticeText("3rd party privacy text") - .setShowTermsAsCheckbox(true) - .setRequestTermsAndConditions(true) - .setAcceptTermsAndConditionsText("accept terms") - .setTermsAndConditionsState( - TermsAndConditionsState.ACCEPTED)) - .build()); + list.add(ActionProto.newBuilder() + .setCollectUserData(CollectUserDataProto.newBuilder() + .setRequestPaymentMethod(true) + .setBillingAddressName("billing_address") + .addSupportedBasicCardNetworks("visa") + .setRequestTermsAndConditions(false)) + .build()); RequiredFieldProto fallbackTextField = RequiredFieldProto.newBuilder() @@ -210,12 +203,6 @@ startAutofillAssistant(mTestRule.getActivity(), testService); waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed()); - onView(allOf(isDescendantOfA(withTagValue( - is(AssistantTagsForTesting - .COLLECT_USER_DATA_CHECKBOX_TERMS_SECTION_TAG))), - withId(R.id.collect_data_privacy_notice))) - .check(matches(isDisplayed())); - onView(withText("Continue")).perform(click()); waitUntilViewMatchesCondition(withId(R.id.card_unmask_input), isCompletelyDisplayed()); onView(withId(R.id.card_unmask_input)).perform(typeText("123"), pressImeActionButton()); @@ -230,6 +217,65 @@ assertThat(getElementValue(getWebContents(), "js_dropdown_value"), is("2050")); } + /** + * Fill a form with a saved contact's details. + */ + @Test + @MediumTest + public void testEnterContact() throws Exception { + mHelper.addDummyProfile("John Doe", "johndoe@gmail.com"); + + ArrayList<ActionProto> list = new ArrayList<>(); + list.add( + ActionProto.newBuilder() + .setCollectUserData( + CollectUserDataProto.newBuilder() + .setContactDetails(ContactDetailsProto.newBuilder() + .setContactDetailsName("contact") + .setRequestPayerName(true) + .setRequestPayerEmail(true)) + .setRequestTermsAndConditions(false)) + .build()); + + RequiredFieldProto nameField = RequiredFieldProto.newBuilder() + .setValueExpression(buildValueExpression(7)) + .setElement(toCssSelector("#profile_name")) + .setForced(true) // Make sure we do actual work. + .build(); + RequiredFieldProto emailField = RequiredFieldProto.newBuilder() + .setValueExpression(buildValueExpression(9)) + .setElement(toCssSelector("#email")) + .setForced(true) // Make sure we do actual work. + .build(); + list.add(ActionProto.newBuilder() + .setUseAddress(UseAddressProto.newBuilder() + .setName("contact") + .setFormFieldElement(toCssSelector("#profile_name")) + .addRequiredFields(nameField) + .addRequiredFields(emailField)) + .build()); + list.add(ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices( + PromptProto.Choice.newBuilder())) + .build()); + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + SupportedScriptProto.newBuilder() + .setPath("form_target_website.html") + .setPresentation(PresentationProto.newBuilder().setAutostart(true)) + .build(), + list); + + AutofillAssistantTestService testService = + new AutofillAssistantTestService(Collections.singletonList(script)); + startAutofillAssistant(mTestRule.getActivity(), testService); + + waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed()); + onView(withText("Continue")).perform(click()); + waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed(), 6000L); + assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe")); + assertThat(getElementValue(getWebContents(), "email"), is("johndoe@gmail.com")); + } + @Test @MediumTest public void testFailingAutofillSendsProperError() throws Exception {
diff --git a/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantPaymentInstrumentEditorAutofill.java b/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantPaymentInstrumentEditorAutofill.java index 4ef3b7cb..6e7ed83 100644 --- a/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantPaymentInstrumentEditorAutofill.java +++ b/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantPaymentInstrumentEditorAutofill.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.content.Context; +import android.text.TextUtils; import androidx.annotation.Nullable; @@ -29,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; /** * Editor for credit cards in Chrome using Autofill as a base. @@ -117,6 +119,12 @@ Callback<AutofillPaymentInstrument> editorDoneCallback = editedPaymentInstrument -> { assert (editedPaymentInstrument != null && editedPaymentInstrument.isComplete() && editedPaymentInstrument.getCard() != null); + if (TextUtils.isEmpty(editedPaymentInstrument.getCard().getGUID())) { + // b/231645674: In the case where the card is not stored, it will come without GUID. + // Combined with the missing "update" signal from the PersonalDataManager this + // causes our UI to show the card twice. + editedPaymentInstrument.getCard().setGUID(UUID.randomUUID().toString()); + } doneCallback.onResult(new PaymentInstrumentModel( AssistantAutofillUtilChrome .autofillPaymentInstrumentToAssistantPaymentInstrument(
diff --git a/chrome/android/java/src/PRESUBMIT.py b/chrome/android/java/src/PRESUBMIT.py index fcac8d4..6ce7516a 100644 --- a/chrome/android/java/src/PRESUBMIT.py +++ b/chrome/android/java/src/PRESUBMIT.py
@@ -96,7 +96,6 @@ BROWSER_ROOT + r'settings[\\\/].*', SIGNIN_UI_BROWSER_ROOT + 'ConfirmManagedSyncDataDialog.java', SIGNIN_UI_BROWSER_ROOT + 'ConfirmSyncDataStateMachineDelegate.java', - SIGNIN_UI_BROWSER_ROOT + 'SignOutDialogFragment.java', BROWSER_ROOT + 'site_settings/AddExceptionPreference.java', BROWSER_ROOT + 'site_settings/ChosenObjectSettings.java', BROWSER_ROOT + 'site_settings/ManageSpaceActivity.java',
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index eb86680..e309f93d 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -167,6 +167,7 @@ "//chrome/gpu", "//chrome/renderer", "//chrome/utility", + "//components/about_ui", "//components/gwp_asan/buildflags", "//components/heap_profiling/in_process", "//components/nacl/common:buildflags",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index 62734c7a..d4a26f08e 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS
@@ -20,6 +20,7 @@ "+components/component_updater", "+components/content_settings/core/common/content_settings_pattern.h", "+components/crash", + "+components/about_ui", "+components/externalauth", "+components/gwp_asan/buildflags/buildflags.h", "+components/gwp_asan/client/gwp_asan.h",
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 56545c6..6ca1b7d 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -15,6 +15,7 @@ #include "base/cpu_reduction_experiment.h" #include "base/dcheck_is_on.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/i18n/rtl.h" #include "base/immediate_crash.h" #include "base/lazy_instance.h" @@ -117,6 +118,7 @@ #include <signal.h> #include "chrome/app/chrome_crash_reporter_client.h" +#include "components/about_ui/credit_utils.h" #endif #if BUILDFLAG(ENABLE_NACL) && (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) @@ -332,6 +334,52 @@ } #if BUILDFLAG(IS_POSIX) +bool HandleCreditsSwitch(const base::CommandLine& command_line) { + if (!command_line.HasSwitch(switches::kCredits)) + return false; + + // Load resources: about_credits.html is in component_resources.pak that is + // re-packed into resources.pak. + base::FilePath resource_dir; + bool result = base::PathService::Get(base::DIR_ASSETS, &resource_dir); + DCHECK(result); + + const std::string locale = + command_line.GetSwitchValueASCII(::switches::kLang); + ui::ResourceBundle::InitSharedInstanceWithLocale( + locale, /**parameter_name=*/nullptr, + ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES); + base::FilePath resources_pak = + resource_dir.Append(FILE_PATH_LITERAL("resources.pak")); + +#if BUILDFLAG(IS_MAC) && !defined(COMPONENT_BUILD) + // In non-component builds, check if a fallback in Resources/ folder is + // available. + if (!base::PathExists(resources_pak)) { + resources_pak = + resource_dir.Append(FILE_PATH_LITERAL("Resources/resources.pak")); + } +#endif + + ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( + resources_pak, ui::kScaleFactorNone); + + auto credits = about_ui::GetCredits(/**include_scripts=*/false); + // If resources failed to load, about_ui::GetCredits returns + // a malformed HTML doc containing `</body>\n</html>`. + // When the resources loaded successfully, we get a huge document + // (~8 MiB) instead. + // We use a threshold of 100 characters to see if the resources + // were loaded successfully. + size_t resource_loading_threshold = 100; + if (credits.size() < resource_loading_threshold) + printf("%s\n", "Failed to load credits."); + else + printf("%s\n", credits.c_str()); + + return true; +} + // Check for --version and --product-version; return true if we encountered // one of these switches and should exit now. bool HandleVersionSwitches(const base::CommandLine& command_line) { @@ -812,6 +860,10 @@ *exit_code = 0; return true; // Got a --version switch; exit with a success error code. } + if (HandleCreditsSwitch(command_line)) { + *exit_code = 0; + return true; // Got a --credits switch; exit with a success error code. + } // TODO(crbug.com/1052397): Revisit the macro expression once build flag // switch of lacros-chrome is complete. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 4e2f334..c3a56c0 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4151,6 +4151,9 @@ {"terminal-dev", flag_descriptions::kTerminalDevName, flag_descriptions::kTerminalDevDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kTerminalDev)}, + {"terminal-multi-profile", flag_descriptions::kTerminalMultiProfileName, + flag_descriptions::kTerminalMultiProfileDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kTerminalMultiProfile)}, {"terminal-tmux-integration", flag_descriptions::kTerminalTmuxIntegrationName, flag_descriptions::kTerminalTmuxIntegrationDescription, kOsCrOS, @@ -7804,6 +7807,10 @@ flag_descriptions::kSanitizerApiDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kSanitizerAPI)}, + {"sanitizer-api-v0", flag_descriptions::kSanitizerApiv0Name, + flag_descriptions::kSanitizerApiv0Description, kOsAll, + FEATURE_VALUE_TYPE(blink::features::kSanitizerAPIv0)}, + #if BUILDFLAG(IS_CHROMEOS_ASH) {"productivity-reorder-apps", flag_descriptions::kLauncherAppSortName, flag_descriptions::kLauncherAppSortDescription, kOsCrOS,
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc index 75dc9e1..c9cea95 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc +++ b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/apps/app_service/browser_app_instance.h" #include "chrome/browser/apps/app_service/browser_app_instance_observer.h" #include "chrome/browser/apps/app_service/browser_app_instance_tracker.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/crosh_system_web_app_info.h" #include "chrome/browser/devtools/devtools_window_testing.h" #include "chrome/browser/profiles/profile_manager.h" @@ -16,7 +17,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_id.h" @@ -718,8 +718,8 @@ IN_PROC_BROWSER_TEST_F(BrowserAppInstanceTrackerTest, TabbedSystemWebApp) { // Make sure we can use crosh. Profile* profile = ProfileManager::GetPrimaryUserProfile(); - DCHECK(web_app::SystemWebAppManager::Get(profile)); - web_app::SystemWebAppManager::Get(profile)->InstallSystemAppsForTesting(); + DCHECK(ash::SystemWebAppManager::Get(profile)); + ash::SystemWebAppManager::Get(profile)->InstallSystemAppsForTesting(); Browser* browser = nullptr; aura::Window* window = nullptr;
diff --git a/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc b/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc index f1367da..7d254b4d 100644 --- a/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc +++ b/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc
@@ -8,10 +8,10 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_install_info.h" @@ -39,7 +39,7 @@ } AppId InstallSystemWebApp() { - web_app::SystemWebAppManager::Get(profile())->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::Get(profile())->InstallSystemAppsForTesting(); return *web_app::GetAppIdForSystemWebApp(profile(), ash::SystemWebAppType::HELP);
diff --git a/chrome/browser/apps/intent_helper/common_apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/common_apps_navigation_throttle.cc index ef5c2740..dfa306e3 100644 --- a/chrome/browser/apps/intent_helper/common_apps_navigation_throttle.cc +++ b/chrome/browser/apps/intent_helper/common_apps_navigation_throttle.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/policy/system_features_disable_list_policy_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.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"
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index a250072..3c0bd92 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -1053,6 +1053,8 @@ "//chrome/browser:resources", "//chrome/browser/ash/child_accounts/time_limits/web_time_limit_error_page", "//chrome/browser/ash/crosapi:browser_util", + "//chrome/browser/ash/mojo_service_manager", + "//chrome/browser/ash/system_web_apps/types:types", "//chrome/browser/chromeos:attestation_proto", "//chrome/browser/metrics/structured", "//chrome/browser/profiles",
diff --git a/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc b/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc index 8571462..c271453 100644 --- a/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc +++ b/chrome/browser/ash/accessibility/accessibility_extension_api_browsertest.cc
@@ -8,12 +8,12 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/ash/accessibility/accessibility_manager.h" #include "chrome/browser/ash/accessibility/dictation_bubble_test_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/webui_url_constants.h" #include "content/public/test/browser_test.h" @@ -76,8 +76,7 @@ Profile* profile = AccessibilityManager::Get()->profile(); // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); ASSERT_TRUE(RunSubtest("testOpenSettingsSubpage")) << message_; @@ -101,8 +100,7 @@ Profile* profile = AccessibilityManager::Get()->profile(); // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); ASSERT_TRUE(RunSubtest("testOpenSettingsSubpageInvalidSubpage")) << message_;
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc index 502349e..cc5a702 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -120,6 +120,7 @@ #include "chrome/browser/ash/login/startup_utils.h" #include "chrome/browser/ash/login/users/chrome_user_manager.h" #include "chrome/browser/ash/login/wizard_controller.h" +#include "chrome/browser/ash/mojo_service_manager/connection_helper.h" #include "chrome/browser/ash/net/bluetooth_pref_state_observer.h" #include "chrome/browser/ash/net/network_health/network_health_service.h" #include "chrome/browser/ash/net/network_portal_detector_impl.h" @@ -696,6 +697,18 @@ dbus_services_ = std::make_unique<internal::DBusServices>( std::move(feature_list_accessor_)); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshUseCrOSMojoServiceManager)) { + DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kDisableMojoBroker)) + << "Mojo broker must be disabled to use the ChromeOS mojo service " + "manager."; + // Initialize mojo service manager. Note that this depends on the + // |mojo_ipc_support_| in |content::BrowserMainLoop| to be created. + mojo_service_manager_closer_ = + mojo_service_manager::CreateConnectionAndPassCloser(); + } + // Need to be done after LoginState has been initialized in DBusServices(). ::memory::MemoryKillsMonitor::Initialize(); @@ -1587,6 +1600,12 @@ g_browser_process->platform_part()->ShutdownSessionManager(); // Ash needs to be closed before UserManager is destroyed. g_browser_process->platform_part()->DestroyChromeUserManager(); + + // Shutdown mojo service manager. This should be called before the + // |mojo_ipc_support_| in |content::BrowserMainLoop| being reset. It is reset + // after calling |PostMainMessageLoopRun()| and before calling + // |PostDestroyThreads()|. + mojo_service_manager_closer_.RunAndReset(); } void ChromeBrowserMainPartsAsh::PostDestroyThreads() {
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.h b/chrome/browser/ash/chrome_browser_main_parts_ash.h index c947a9a..446d9b4d 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.h +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/callback_helpers.h" #include "base/feature_list.h" #include "base/memory/weak_ptr.h" #include "base/task/cancelable_task_tracker.h" @@ -62,8 +63,8 @@ namespace ash { class AccessibilityEventRewriterDelegateImpl; -class AudioSurveyHandler; class ArcKioskAppManager; +class AudioSurveyHandler; class BluetoothPrefStateObserver; class BulkPrintersCalculatorFactory; class CrosUsbDetector; @@ -79,8 +80,8 @@ class LowDiskNotification; class NetworkPrefStateObserver; class NetworkThrottlingObserver; -class PowerMetricsReporter; class PSIMemoryMetrics; +class PowerMetricsReporter; class RendererFreezer; class SessionTerminationManager; class ShortcutMappingPrefService; @@ -96,6 +97,10 @@ class DBusServices; } +namespace mojo_service_manager { +class Helper; +} + namespace platform_keys { class KeyPermissionsManager; } @@ -172,6 +177,8 @@ std::unique_ptr<internal::DBusServices> dbus_services_; + base::ScopedClosureRunner mojo_service_manager_closer_; + std::unique_ptr<SystemTokenCertDBInitializer> system_token_certdb_initializer_;
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index bff557fd..834a269 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -229,10 +229,6 @@ ? kStabilitySwitchToChannelMap.at(*stability_switch_value) : chrome::GetChannel(); } - -static_assert( - crosapi::mojom::Crosapi::Version_ == 79, - "if you add a new crosapi, please add it to kInterfaceVersionEntries"); } // namespace // NOTE: If you change the lacros component names, you must also update
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc index e066deb8..da417dc 100644 --- a/chrome/browser/ash/crosapi/crosapi_util.cc +++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -186,6 +186,10 @@ return {T::Uuid_, T::Version_}; } +static_assert(crosapi::mojom::Crosapi::Version_ == 79, + "If you add a new crosapi, please add it to " + "kInterfaceVersionEntries below."); + constexpr InterfaceVersionEntry kInterfaceVersionEntries[] = { MakeInterfaceVersionEntry<chromeos::cdm::mojom::BrowserCdmFactory>(), MakeInterfaceVersionEntry< @@ -509,6 +513,7 @@ mojom::DeviceSettingsPtr result = mojom::DeviceSettings::New(); result->attestation_for_content_protection_enabled = MojoOptionalBool::kUnset; + result->device_ephemeral_users_enabled = MojoOptionalBool::kUnset; if (ash::CrosSettings::IsInitialized()) { // It's expected that the CrosSettings values are trusted. The only // theoretical exception is when device ownership is taken on consumer @@ -550,6 +555,14 @@ } result->usb_detachable_allow_list = std::move(allow_list); } + + bool ephemeral_users_enabled = false; + if (cros_settings->GetBoolean(ash::kAccountsPrefEphemeralUsersEnabled, + &ephemeral_users_enabled)) { + result->device_ephemeral_users_enabled = ephemeral_users_enabled + ? MojoOptionalBool::kTrue + : MojoOptionalBool::kFalse; + } } else { LOG(WARNING) << "Unexpected crossettings trusted values status: " << trusted_result;
diff --git a/chrome/browser/ash/crosapi/crosapi_util_unittest.cc b/chrome/browser/ash/crosapi/crosapi_util_unittest.cc index 3958204..554e614 100644 --- a/chrome/browser/ash/crosapi/crosapi_util_unittest.cc +++ b/chrome/browser/ash/crosapi/crosapi_util_unittest.cc
@@ -134,6 +134,9 @@ testing_profile_.ScopedCrosSettingsTestHelper() ->GetStubbedProvider() ->SetBoolean(ash::kAttestationForContentProtectionEnabled, true); + testing_profile_.ScopedCrosSettingsTestHelper() + ->GetStubbedProvider() + ->SetBoolean(ash::kAccountsPrefEphemeralUsersEnabled, false); base::Value allowlist(base::Value::Type::LIST); base::Value ids(base::Value::Type::DICTIONARY); @@ -150,6 +153,8 @@ EXPECT_EQ(settings->attestation_for_content_protection_enabled, crosapi::mojom::DeviceSettings::OptionalBool::kTrue); + EXPECT_EQ(settings->device_ephemeral_users_enabled, + crosapi::mojom::DeviceSettings::OptionalBool::kFalse); ASSERT_EQ(settings->usb_detachable_allow_list->usb_device_ids.size(), 1u); EXPECT_EQ( settings->usb_detachable_allow_list->usb_device_ids[0]->has_vendor_id,
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc index 1696ec4..003d78c5 100644 --- a/chrome/browser/ash/crostini/crostini_manager.cc +++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -2988,6 +2988,9 @@ std::move(callback)); break; case vm_tools::cicerone::CreateLxdContainerResponse::EXISTS: + // Containers are registered in OnContainerCreated() when created via the + // UI. But for any created manually also register now (crbug.com/1330168). + AddNewLxdContainerToPrefs(profile_, container_id); std::move(callback).Run(CrostiniResult::SUCCESS); break; default:
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc index 9d9d6e3..5d40e5a 100644 --- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc +++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -689,6 +689,35 @@ run_loop()->Run(); } +TEST_F(CrostiniManagerTest, RegisterContainerPrefWhenContainerCreated) { + const base::Value* pref = + profile_->GetPrefs()->GetList(crostini::prefs::kCrostiniContainers); + EXPECT_EQ(pref->GetList().size(), 0); + crostini_manager()->CreateLxdContainer( + container_id(), absl::nullopt, absl::nullopt, + base::BindOnce(&ExpectCrostiniResult, run_loop()->QuitClosure(), + CrostiniResult::SUCCESS)); + run_loop()->Run(); + pref = profile_->GetPrefs()->GetList(crostini::prefs::kCrostiniContainers); + EXPECT_EQ(pref->GetList().size(), 1); +} + +TEST_F(CrostiniManagerTest, RegisterContainerPrefWhenContainerExists) { + const base::Value* pref = + profile_->GetPrefs()->GetList(crostini::prefs::kCrostiniContainers); + EXPECT_EQ(pref->GetList().size(), 0); + vm_tools::cicerone::CreateLxdContainerResponse response; + response.set_status(vm_tools::cicerone::CreateLxdContainerResponse::EXISTS); + fake_cicerone_client_->set_create_lxd_container_response(response); + crostini_manager()->CreateLxdContainer( + container_id(), absl::nullopt, absl::nullopt, + base::BindOnce(&ExpectCrostiniResult, run_loop()->QuitClosure(), + CrostiniResult::SUCCESS)); + run_loop()->Run(); + pref = profile_->GetPrefs()->GetList(crostini::prefs::kCrostiniContainers); + EXPECT_EQ(pref->GetList().size(), 1); +} + class CrostiniManagerRestartTest : public CrostiniManagerTest, public CrostiniManager::RestartObserver { public:
diff --git a/chrome/browser/ash/crostini/crostini_terminal.cc b/chrome/browser/ash/crostini/crostini_terminal.cc index 7967c006..f42ceae 100644 --- a/chrome/browser/ash/crostini/crostini_terminal.cc +++ b/chrome/browser/ash/crostini/crostini_terminal.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/guest_os/guest_os_pref_names.h" #include "chrome/browser/ash/guest_os/guest_os_share_path.h" +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -36,7 +37,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/chrome_unscaled_resources.h" @@ -466,21 +466,6 @@ return result; } -std::vector<ContainerId> GetLinuxContainers(Profile* profile) { - std::vector<ContainerId> result; - const base::Value::List& container_list = - profile->GetPrefs() - ->GetList(crostini::prefs::kCrostiniContainers) - ->GetList(); - for (const auto& container : container_list) { - crostini::ContainerId id(container); - if (!id.vm_name.empty() && !id.container_name.empty()) { - result.push_back(std::move(id)); - } - } - return result; -} - void AddTerminalMenuItems(Profile* profile, apps::mojom::MenuItemsPtr* menu_items) { apps::AddCommandItem(ash::SETTINGS, IDS_INTERNAL_APP_SETTINGS, menu_items); @@ -510,7 +495,7 @@ GetSSHConnections(profile); std::vector<ContainerId> containers; if (CrostiniFeatures::Get()->IsEnabled(profile)) { - containers = GetLinuxContainers(profile); + containers = GetContainers(profile); } if (connections.size() > 0 || containers.size() > 0) { apps::AddSeparator(ui::DOUBLE_SEPARATOR, &menu_items);
diff --git a/chrome/browser/ash/crostini/crostini_terminal.h b/chrome/browser/ash/crostini/crostini_terminal.h index cf4196e..44c3f2d 100644 --- a/chrome/browser/ash/crostini/crostini_terminal.h +++ b/chrome/browser/ash/crostini/crostini_terminal.h
@@ -162,9 +162,6 @@ std::vector<std::pair<std::string, std::string>> GetSSHConnections( Profile* profile); -// Returns list of Linux containers. -std::vector<ContainerId> GetLinuxContainers(Profile* profile); - // Add terminal menu items (Settings, Shut down Linux). void AddTerminalMenuItems(Profile* profile, apps::mojom::MenuItemsPtr* menu_items);
diff --git a/chrome/browser/ash/crostini/crostini_terminal_unittest.cc b/chrome/browser/ash/crostini/crostini_terminal_unittest.cc index 926896d6..a769841 100644 --- a/chrome/browser/ash/crostini/crostini_terminal_unittest.cc +++ b/chrome/browser/ash/crostini/crostini_terminal_unittest.cc
@@ -48,19 +48,4 @@ EXPECT_EQ(GetSSHConnections(&profile), expected); } -TEST_F(CrostiniTerminalTest, GetLinuxContainers) { - content::BrowserTaskEnvironment task_environment; - TestingProfile profile; - auto pref = base::JSONReader::Read(R"([ - {"vm_name": "vm1", "container_name": "c1"}, - {"vm_name": "vm2", "container_name": "c2"}, - {"vm_name": "vm3"} - ])"); - ASSERT_TRUE(pref.has_value()); - profile.GetPrefs()->Set(prefs::kCrostiniContainers, std::move(*pref)); - std::vector<ContainerId> expected = {ContainerId("vm1", "c1"), - ContainerId("vm2", "c2")}; - EXPECT_EQ(GetLinuxContainers(&profile), expected); -} - } // namespace crostini
diff --git a/chrome/browser/ash/crostini/crostini_util.cc b/chrome/browser/ash/crostini/crostini_util.cc index 6f9c35c1..0d0429f 100644 --- a/chrome/browser/ash/crostini/crostini_util.cc +++ b/chrome/browser/ash/crostini/crostini_util.cc
@@ -442,6 +442,21 @@ } } +std::vector<ContainerId> GetContainers(Profile* profile) { + std::vector<ContainerId> result; + const base::Value::List& container_list = + profile->GetPrefs() + ->GetList(crostini::prefs::kCrostiniContainers) + ->GetList(); + for (const auto& container : container_list) { + crostini::ContainerId id(container); + if (!id.vm_name.empty() && !id.container_name.empty()) { + result.push_back(std::move(id)); + } + } + return result; +} + void AddNewLxdContainerToPrefs(Profile* profile, const ContainerId& container_id) { ListPrefUpdate updater(profile->GetPrefs(),
diff --git a/chrome/browser/ash/crostini/crostini_util.h b/chrome/browser/ash/crostini/crostini_util.h index 7fc4bb4..318cb92 100644 --- a/chrome/browser/ash/crostini/crostini_util.h +++ b/chrome/browser/ash/crostini/crostini_util.h
@@ -189,6 +189,9 @@ // Remove duplicate containers in the existing kCrostiniContainers pref. void RemoveDuplicateContainerEntries(PrefService* prefs); +// Returns a list of all containers in prefs. +std::vector<ContainerId> GetContainers(Profile* profile); + // Add a newly created LXD container to the kCrostiniContainers pref void AddNewLxdContainerToPrefs(Profile* profile, const ContainerId& container_id);
diff --git a/chrome/browser/ash/crostini/crostini_util_unittest.cc b/chrome/browser/ash/crostini/crostini_util_unittest.cc index 7078a56..81ffa38 100644 --- a/chrome/browser/ash/crostini/crostini_util_unittest.cc +++ b/chrome/browser/ash/crostini/crostini_util_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ash/crostini/crostini_util.h" #include "base/bind.h" +#include "base/json/json_reader.h" #include "base/run_loop.h" #include "chrome/browser/ash/crostini/crostini_manager.h" #include "chrome/browser/ash/crostini/crostini_pref_names.h" @@ -229,4 +230,17 @@ EXPECT_FALSE(ShouldStopVm(profile_.get(), containera)); } + +TEST_F(CrostiniUtilTest, GetContainers) { + auto pref = base::JSONReader::Read(R"([ + {"vm_name": "vm1", "container_name": "c1"}, + {"vm_name": "vm2", "container_name": "c2"}, + {"vm_name": "vm3"} + ])"); + ASSERT_TRUE(pref.has_value()); + profile_->GetPrefs()->Set(prefs::kCrostiniContainers, std::move(*pref)); + std::vector<ContainerId> expected = {ContainerId("vm1", "c1"), + ContainerId("vm2", "c2")}; + EXPECT_EQ(GetContainers(profile_.get()), expected); +} } // namespace crostini
diff --git a/chrome/browser/ash/file_manager/external_filesystem_apitest.cc b/chrome/browser/ash/file_manager/external_filesystem_apitest.cc index 554b595..219334d 100644 --- a/chrome/browser/ash/file_manager/external_filesystem_apitest.cc +++ b/chrome/browser/ash/file_manager/external_filesystem_apitest.cc
@@ -19,13 +19,13 @@ #include "chrome/browser/ash/file_manager/mount_test_util.h" #include "chrome/browser/ash/file_manager/volume_manager.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/cast_config_controller_media_router.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" @@ -704,7 +704,7 @@ void SetUpOnMainThread() override { Profile* profile = browser()->profile(); file_manager::test::AddDefaultComponentExtensionsOnMainThread(profile); - web_app::SystemWebAppManager::GetForTest(profile) + ash::SystemWebAppManager::GetForTest(profile) ->InstallSystemAppsForTesting(); LocalFileSystemExtensionApiTest::SetUpOnMainThread(); }
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc index 45f1e83..8aad7da7b 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -78,6 +78,7 @@ #include "chrome/browser/ash/guest_os/public/types.h" #include "chrome/browser/ash/smb_client/smb_service.h" #include "chrome/browser/ash/smb_client/smb_service_factory.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/extensions/file_manager/event_router.h" @@ -95,7 +96,6 @@ #include "chrome/browser/ui/views/extensions/extension_dialog.h" #include "chrome/browser/ui/views/select_file_dialog_extension.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_features.h" @@ -2097,7 +2097,7 @@ // Enable System Web Apps if needed. if (options.media_swa || options.files_swa) { - web_app::SystemWebAppManager::GetForTest(profile()) + ash::SystemWebAppManager::GetForTest(profile()) ->InstallSystemAppsForTesting(); }
diff --git a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc index 10fbc884..60d062e7 100644 --- a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
@@ -19,10 +19,10 @@ #include "chrome/browser/ash/file_manager/filesystem_api_util.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/file_manager/volume_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/web_applications/web_app_launch_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/profile_test_helper.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_id_constants.h" @@ -112,7 +112,7 @@ public: void SetUpOnMainThread() override { test::AddDefaultComponentExtensionsOnMainThread(browser()->profile()); - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); }
diff --git a/chrome/browser/ash/first_run/first_run.cc b/chrome/browser/ash/first_run/first_run.cc index f912e49b..ac8d947 100644 --- a/chrome/browser/ash/first_run/first_run.cc +++ b/chrome/browser/ash/first_run/first_run.cc
@@ -14,13 +14,13 @@ #include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/login/ui/login_display_host.h" #include "chrome/browser/ash/login/wizard_controller.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_observer.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" @@ -90,7 +90,7 @@ private: explicit AppLauncher(Profile* profile) : profile_(profile) { profile->AddObserver(this); - web_app::SystemWebAppManager::Get(profile)->on_apps_synchronized().Post( + ash::SystemWebAppManager::Get(profile)->on_apps_synchronized().Post( FROM_HERE, base::BindOnce(&AppLauncher::LaunchHelpApp, AsWeakPtr())); }
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc index 94646de..2adb025 100644 --- a/chrome/browser/ash/login/session/user_session_manager.cc +++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -775,15 +775,14 @@ DCHECK(user); if (network_connection_tracker_ && !network_connection_tracker_->IsOffline()) { - pending_signin_restore_sessions_.erase(user->GetAccountId().GetUserEmail()); + pending_signin_restore_sessions_.erase(user->GetAccountId()); RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); } else { // Even if we're online we should wait till initial // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may // end up canceling all request when initial network connection type is // processed. See http://crbug.com/121643. - pending_signin_restore_sessions_.insert( - user->GetAccountId().GetUserEmail()); + pending_signin_restore_sessions_.insert(user->GetAccountId()); } } @@ -1145,8 +1144,8 @@ // If we come online for the first time after successful offline login, // we need to kick off OAuth token verification process again. login_manager->ContinueSessionRestore(); - } else if (pending_signin_restore_sessions_.erase( - user->GetAccountId().GetUserEmail()) > 0) { + } else if (pending_signin_restore_sessions_.erase(user->GetAccountId()) > + 0) { // Restore it, if the account is contained in the pending set. RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); }
diff --git a/chrome/browser/ash/login/session/user_session_manager.h b/chrome/browser/ash/login/session/user_session_manager.h index 6e25f108..1896d47 100644 --- a/chrome/browser/ash/login/session/user_session_manager.h +++ b/chrome/browser/ash/login/session/user_session_manager.h
@@ -376,7 +376,7 @@ friend class test::UserSessionManagerTestApi; friend struct base::DefaultSingletonTraits<UserSessionManager>; - typedef std::set<std::string> SigninSessionRestoreStateSet; + using SigninSessionRestoreStateSet = std::set<AccountId>; void SetNetworkConnectionTracker( network::NetworkConnectionTracker* network_connection_tracker);
diff --git a/chrome/browser/ash/mojo_service_manager/BUILD.gn b/chrome/browser/ash/mojo_service_manager/BUILD.gn new file mode 100644 index 0000000..27c85935 --- /dev/null +++ b/chrome/browser/ash/mojo_service_manager/BUILD.gn
@@ -0,0 +1,21 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") +import("//chromeos/features.gni") + +assert(is_chromeos_ash) + +source_set("mojo_service_manager") { + sources = [ + "connection_helper.cc", + "connection_helper.h", + ] + deps = [ + "//base", + "//chromeos:features", + "//chromeos/components/mojo_service_manager", + "//mojo/public/cpp/bindings", + ] +}
diff --git a/chrome/browser/ash/mojo_service_manager/OWNERS b/chrome/browser/ash/mojo_service_manager/OWNERS new file mode 100644 index 0000000..d350deb --- /dev/null +++ b/chrome/browser/ash/mojo_service_manager/OWNERS
@@ -0,0 +1 @@ +file://chromeos/components/mojo_service_manager/OWNERS
diff --git a/chrome/browser/ash/mojo_service_manager/connection_helper.cc b/chrome/browser/ash/mojo_service_manager/connection_helper.cc new file mode 100644 index 0000000..b161dddb --- /dev/null +++ b/chrome/browser/ash/mojo_service_manager/connection_helper.cc
@@ -0,0 +1,68 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/mojo_service_manager/connection_helper.h" + +#include <memory> + +#include "chromeos/components/mojo_service_manager/connection.h" +#include "chromeos/features.h" + +#if !BUILDFLAG(USE_REAL_CHROMEOS_SERVICES) +#include "base/system/sys_info.h" +#include "chromeos/components/mojo_service_manager/fake_mojo_service_manager.h" +#endif + +namespace { + +namespace service_manager = chromeos::mojo_service_manager; + +base::ScopedClosureRunner CreateRealConnectionAndPassCloser() { + service_manager::BootstrapServiceManagerConnection(); + return base::ScopedClosureRunner{ + base::BindOnce(&service_manager::ResetServiceManagerConnection)}; +} + +#if !BUILDFLAG(USE_REAL_CHROMEOS_SERVICES) +void ResetFakeConnection( + std::unique_ptr<service_manager::FakeMojoServiceManager> + fake_service_manager) { + // Reset the connection before the fake service manager so the disconnect + // handler won't be triggered. + service_manager::ResetServiceManagerConnection(); + fake_service_manager.reset(); +} + +base::ScopedClosureRunner CreateFakeConnectionAndPassCloser() { + auto fake_service_manager = + std::make_unique<service_manager::FakeMojoServiceManager>(); + service_manager::SetServiceManagerRemoteForTesting( + fake_service_manager->BindNewPipeAndPassRemote()); + + return base::ScopedClosureRunner{ + base::BindOnce(&ResetFakeConnection, std::move(fake_service_manager))}; +} +#endif + +} // namespace + +namespace ash { +namespace mojo_service_manager { + +base::ScopedClosureRunner CreateConnectionAndPassCloser() { +#if BUILDFLAG(USE_REAL_CHROMEOS_SERVICES) + return CreateRealConnectionAndPassCloser(); +#else + // TODO(crbug.com/952745): Always use fakes after adding + // use_real_chromeos_services=true to where needed. + if (base::SysInfo::IsRunningOnChromeOS()) { + return CreateRealConnectionAndPassCloser(); + } else { + return CreateFakeConnectionAndPassCloser(); + } +#endif +} + +} // namespace mojo_service_manager +} // namespace ash
diff --git a/chrome/browser/ash/mojo_service_manager/connection_helper.h b/chrome/browser/ash/mojo_service_manager/connection_helper.h new file mode 100644 index 0000000..93615b92 --- /dev/null +++ b/chrome/browser/ash/mojo_service_manager/connection_helper.h
@@ -0,0 +1,22 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_MOJO_SERVICE_MANAGER_CONNECTION_HELPER_H_ +#define CHROME_BROWSER_ASH_MOJO_SERVICE_MANAGER_CONNECTION_HELPER_H_ + +#include <base/callback_helpers.h> + +namespace ash { +namespace mojo_service_manager { + +// Creates the connection to mojo service manager and returns a +// base::ScopedClosureRunner which can close the connection. This connects to a +// fake implementation if the build target is not going to use real ChromeOS +// services. +base::ScopedClosureRunner CreateConnectionAndPassCloser(); + +} // namespace mojo_service_manager +} // namespace ash + +#endif // CHROME_BROWSER_ASH_MOJO_SERVICE_MANAGER_CONNECTION_HELPER_H_
diff --git a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc similarity index 82% rename from chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc rename to chrome/browser/ash/system_web_apps/system_web_app_manager.cc index 2dd50df..3940176 100644 --- a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc +++ b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include <algorithm> #include <memory> @@ -100,7 +100,7 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) -namespace web_app { +namespace ash { namespace { @@ -108,9 +108,9 @@ // bailing out. const int kInstallFailureAttempts = 3; -ash::SystemWebAppDelegateMap CreateSystemWebApps(Profile* profile) { +SystemWebAppDelegateMap CreateSystemWebApps(Profile* profile) { #if BUILDFLAG(IS_CHROMEOS_ASH) - std::vector<std::unique_ptr<ash::SystemWebAppDelegate>> info_vec; + std::vector<std::unique_ptr<SystemWebAppDelegate>> info_vec; // TODO(crbug.com/1051229): Currently unused, will be hooked up // post-migration. We're making delegates for everything, and will then use // them in place of SystemAppInfos. @@ -119,7 +119,7 @@ info_vec.push_back(std::make_unique<OSSettingsSystemAppDelegate>(profile)); info_vec.push_back(std::make_unique<CroshSystemAppDelegate>(profile)); info_vec.push_back(std::make_unique<TerminalSystemAppDelegate>(profile)); - info_vec.push_back(std::make_unique<ash::HelpAppSystemAppDelegate>(profile)); + info_vec.push_back(std::make_unique<HelpAppSystemAppDelegate>(profile)); info_vec.push_back(std::make_unique<MediaSystemAppDelegate>(profile)); info_vec.push_back( std::make_unique<PrintManagementSystemAppDelegate>(profile)); @@ -146,12 +146,12 @@ info_vec.push_back(std::make_unique<SampleSystemAppDelegate>(profile)); #endif // !defined(OFFICIAL_BUILD) - ash::SystemWebAppDelegateMap delegate_map; + SystemWebAppDelegateMap delegate_map; for (auto& info : info_vec) { if (info->IsAppEnabled() || - base::FeatureList::IsEnabled(features::kEnableAllSystemWebApps)) { + base::FeatureList::IsEnabled(::features::kEnableAllSystemWebApps)) { // Gets `type` before std::move(). - ash::SystemWebAppType type = info->GetType(); + SystemWebAppType type = info->GetType(); delegate_map.emplace(type, std::move(info)); } } @@ -166,24 +166,24 @@ url.SchemeIs(content::kChromeUIUntrustedScheme); } -ExternalInstallOptions CreateInstallOptionsForSystemApp( - const ash::SystemWebAppType type, - const ash::SystemWebAppDelegate& delegate, +web_app::ExternalInstallOptions CreateInstallOptionsForSystemApp( + const SystemWebAppType type, + const SystemWebAppDelegate& delegate, bool force_update, bool is_disabled) { DCHECK(delegate.GetInstallUrl().scheme() == content::kChromeUIScheme || delegate.GetInstallUrl().scheme() == content::kChromeUIUntrustedScheme); - ExternalInstallOptions install_options( - delegate.GetInstallUrl(), UserDisplayMode::kStandalone, - ExternalInstallSource::kSystemInstalled); + web_app::ExternalInstallOptions install_options( + delegate.GetInstallUrl(), web_app::UserDisplayMode::kStandalone, + web_app::ExternalInstallSource::kSystemInstalled); install_options.only_use_app_info_factory = true; // This can be Unretained because it's referring to the delegate owning this // factory method. The lifetime of that is the same as the // SystemWebAppManager. install_options.app_info_factory = base::BindRepeating( - &ash::SystemWebAppDelegate::GetWebAppInfo, base::Unretained(&delegate)); + &SystemWebAppDelegate::GetWebAppInfo, base::Unretained(&delegate)); install_options.add_to_applications_menu = delegate.ShouldShowInLauncher(); install_options.add_to_desktop = false; install_options.add_to_quick_launch_bar = false; @@ -217,14 +217,14 @@ on_tasks_started_(new base::OneShotEvent()), install_result_per_profile_histogram_name_( std::string(kInstallResultHistogramName) + ".Profiles." + - GetProfileCategoryForLogging(profile)), + web_app::GetProfileCategoryForLogging(profile)), pref_service_(profile_->GetPrefs()) { if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) { // Always update in tests. update_policy_ = UpdatePolicy::kAlwaysUpdate; // Populate with real system apps if the test asks for it. - if (base::FeatureList::IsEnabled(features::kEnableAllSystemWebApps)) + if (base::FeatureList::IsEnabled(::features::kEnableAllSystemWebApps)) system_app_delegates_ = CreateSystemWebApps(profile_); return; @@ -245,10 +245,11 @@ // static SystemWebAppManager* SystemWebAppManager::Get(Profile* profile) { - if (!AreSystemWebAppsSupported()) + if (!web_app::AreSystemWebAppsSupported()) return nullptr; - WebAppProvider* provider = WebAppProvider::GetForLocalAppsUnchecked(profile); + web_app::WebAppProvider* provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile); if (!provider) return nullptr; @@ -259,7 +260,8 @@ // static SystemWebAppManager* SystemWebAppManager::GetForLocalAppsUnchecked( Profile* profile) { - WebAppProvider* provider = WebAppProvider::GetForLocalAppsUnchecked(profile); + web_app::WebAppProvider* provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile); if (!provider) return nullptr; @@ -269,7 +271,8 @@ // static SystemWebAppManager* SystemWebAppManager::GetForTest(Profile* profile) { - WebAppProvider* provider = WebAppProvider::GetForTest(profile); + web_app::WebAppProvider* provider = + web_app::WebAppProvider::GetForTest(profile); if (!provider) return nullptr; @@ -283,8 +286,8 @@ } } -bool SystemWebAppManager::IsAppEnabled(ash::SystemWebAppType type) const { - return ash::IsSystemWebAppEnabled(system_app_delegates_, type); +bool SystemWebAppManager::IsAppEnabled(SystemWebAppType type) const { + return IsSystemWebAppEnabled(system_app_delegates_, type); } void SystemWebAppManager::Shutdown() { @@ -293,11 +296,11 @@ } void SystemWebAppManager::SetSubsystems( - ExternallyManagedAppManager* externally_managed_app_manager, - WebAppRegistrar* registrar, - WebAppSyncBridge* sync_bridge, - WebAppUiManager* ui_manager, - WebAppPolicyManager* web_app_policy_manager) { + web_app::ExternallyManagedAppManager* externally_managed_app_manager, + web_app::WebAppRegistrar* registrar, + web_app::WebAppSyncBridge* sync_bridge, + web_app::WebAppUiManager* ui_manager, + web_app::WebAppPolicyManager* web_app_policy_manager) { externally_managed_app_manager_ = externally_managed_app_manager; registrar_ = registrar; sync_bridge_ = sync_bridge; @@ -325,7 +328,7 @@ } #endif // DCHECK_IS_ON() - std::vector<ExternalInstallOptions> install_options_list; + std::vector<web_app::ExternalInstallOptions> install_options_list; const bool should_force_install_apps = ShouldForceInstallApps(); if (should_force_install_apps) { UpdateLastAttemptedInfo(); @@ -349,7 +352,8 @@ } externally_managed_app_manager_->SynchronizeInstalledApps( - std::move(install_options_list), ExternalInstallSource::kSystemInstalled, + std::move(install_options_list), + web_app::ExternalInstallSource::kSystemInstalled, base::BindOnce(&SystemWebAppManager::OnAppsSynchronized, weak_ptr_factory_.GetWeakPtr(), should_force_install_apps, install_start_time)); @@ -367,27 +371,27 @@ run_loop.Run(); } -absl::optional<AppId> SystemWebAppManager::GetAppIdForSystemApp( - ash::SystemWebAppType type) const { +absl::optional<web_app::AppId> SystemWebAppManager::GetAppIdForSystemApp( + SystemWebAppType type) const { return web_app::GetAppIdForSystemApp(*registrar_, system_app_delegates_, type); } -absl::optional<ash::SystemWebAppType> -SystemWebAppManager::GetSystemAppTypeForAppId(const AppId& app_id) const { +absl::optional<SystemWebAppType> SystemWebAppManager::GetSystemAppTypeForAppId( + const web_app::AppId& app_id) const { return web_app::GetSystemAppTypeForAppId(*registrar_, system_app_delegates_, app_id); } -const ash::SystemWebAppDelegate* SystemWebAppManager::GetSystemApp( - ash::SystemWebAppType type) const { - return ash::GetSystemWebApp(system_app_delegates_, type); +const SystemWebAppDelegate* SystemWebAppManager::GetSystemApp( + SystemWebAppType type) const { + return GetSystemWebApp(system_app_delegates_, type); } -std::vector<AppId> SystemWebAppManager::GetAppIds() const { - std::vector<AppId> app_ids; +std::vector<web_app::AppId> SystemWebAppManager::GetAppIds() const { + std::vector<web_app::AppId> app_ids; for (const auto& app_type_to_app_info : system_app_delegates_) { - absl::optional<AppId> app_id = + absl::optional<web_app::AppId> app_id = GetAppIdForSystemApp(app_type_to_app_info.first); if (app_id.has_value()) { app_ids.push_back(app_id.value()); @@ -396,12 +400,12 @@ return app_ids; } -bool SystemWebAppManager::IsSystemWebApp(const AppId& app_id) const { +bool SystemWebAppManager::IsSystemWebApp(const web_app::AppId& app_id) const { return web_app::IsSystemWebApp(*registrar_, system_app_delegates_, app_id); } const std::vector<std::string>* SystemWebAppManager::GetEnabledOriginTrials( - const ash::SystemWebAppDelegate* system_app, + const SystemWebAppDelegate* system_app, const GURL& url) const { DCHECK(system_app); const auto& origin_to_origin_trials = system_app->GetEnabledOriginTrials(); @@ -414,13 +418,13 @@ } void SystemWebAppManager::OnReadyToCommitNavigation( - const AppId& app_id, + const web_app::AppId& app_id, content::NavigationHandle* navigation_handle) { // No need to setup origin trials for intra-document navigation. if (navigation_handle->IsSameDocument()) return; - const absl::optional<ash::SystemWebAppType> type = + const absl::optional<SystemWebAppType> type = GetSystemAppTypeForAppId(app_id); // This function should only be called when an navigation happens inside a // System App. So the |app_id| should always have a valid associated System @@ -436,22 +440,23 @@ } } -absl::optional<ash::SystemWebAppType> +absl::optional<SystemWebAppType> SystemWebAppManager::GetCapturingSystemAppForURL(const GURL& url) const { if (!HasSystemWebAppScheme(url)) return absl::nullopt; - absl::optional<AppId> app_id = registrar_->FindAppWithUrlInScope(url); + absl::optional<web_app::AppId> app_id = + registrar_->FindAppWithUrlInScope(url); if (!app_id.has_value()) return absl::nullopt; - absl::optional<ash::SystemWebAppType> type = + absl::optional<SystemWebAppType> type = GetSystemAppTypeForAppId(app_id.value()); if (!type.has_value()) return absl::nullopt; - const ash::SystemWebAppDelegate* delegate = - ash::GetSystemWebApp(system_app_delegates_, type.value()); + const SystemWebAppDelegate* delegate = + GetSystemWebApp(system_app_delegates_, type.value()); if (!delegate) return absl::nullopt; @@ -461,12 +466,11 @@ // TODO(crbug://1051229): Expand ShouldCaptureNavigation to take a GURL, and // move this into the camera one. #if BUILDFLAG(IS_CHROMEOS_ASH) - if (type == ash::SystemWebAppType::CAMERA) { + if (type == SystemWebAppType::CAMERA) { GURL::Replacements replacements; replacements.ClearQuery(); replacements.ClearRef(); - if (url.ReplaceComponents(replacements).spec() != - ash::kChromeUICameraAppMainURL) + if (url.ReplaceComponents(replacements).spec() != kChromeUICameraAppMainURL) return absl::nullopt; } #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -475,11 +479,11 @@ } void SystemWebAppManager::SetSystemAppsForTesting( - ash::SystemWebAppDelegateMap system_apps) { + SystemWebAppDelegateMap system_apps) { system_app_delegates_ = std::move(system_apps); } -const std::vector<std::unique_ptr<ash::SystemWebAppBackgroundTask>>& +const std::vector<std::unique_ptr<SystemWebAppBackgroundTask>>& SystemWebAppManager::GetBackgroundTasksForTesting() { return tasks_; } @@ -495,11 +499,11 @@ // static void SystemWebAppManager::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterStringPref(prefs::kSystemWebAppLastUpdateVersion, ""); - registry->RegisterStringPref(prefs::kSystemWebAppLastInstalledLocale, ""); - registry->RegisterStringPref(prefs::kSystemWebAppLastAttemptedVersion, ""); - registry->RegisterStringPref(prefs::kSystemWebAppLastAttemptedLocale, ""); - registry->RegisterIntegerPref(prefs::kSystemWebAppInstallFailureCount, 0); + registry->RegisterStringPref(::prefs::kSystemWebAppLastUpdateVersion, ""); + registry->RegisterStringPref(::prefs::kSystemWebAppLastInstalledLocale, ""); + registry->RegisterStringPref(::prefs::kSystemWebAppLastAttemptedVersion, ""); + registry->RegisterStringPref(::prefs::kSystemWebAppLastAttemptedLocale, ""); + registry->RegisterIntegerPref(::prefs::kSystemWebAppInstallFailureCount, 0); } const base::Version& SystemWebAppManager::CurrentVersion() const { @@ -523,13 +527,14 @@ } void SystemWebAppManager::RecordSystemWebAppInstallResults( - const std::map<GURL, ExternallyManagedAppManager::InstallResult>& + const std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult>& install_results) const { // Report install result codes. Exclude kSuccessAlreadyInstalled from metrics. // This result means the installation pipeline is a no-op (which happens every // time user logs in, and if there hasn't been a version upgrade). This skews // the install success rate. - std::map<GURL, ExternallyManagedAppManager::InstallResult> results_to_report; + std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult> + results_to_report; std::copy_if(install_results.begin(), install_results.end(), std::inserter(results_to_report, results_to_report.end()), [](const auto& url_and_result) { @@ -573,18 +578,19 @@ void SystemWebAppManager::OnAppsSynchronized( bool did_force_install_apps, const base::TimeTicks& install_start_time, - std::map<GURL, ExternallyManagedAppManager::InstallResult> install_results, + std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult> + install_results, std::map<GURL, bool> uninstall_results) { const base::TimeDelta install_duration = base::TimeTicks::Now() - install_start_time; // TODO(qjw): Figure out where install_results come from, decide if // installation failures need to be handled - pref_service_->SetString(prefs::kSystemWebAppLastUpdateVersion, + pref_service_->SetString(::prefs::kSystemWebAppLastUpdateVersion, CurrentVersion().GetString()); - pref_service_->SetString(prefs::kSystemWebAppLastInstalledLocale, + pref_service_->SetString(::prefs::kSystemWebAppLastInstalledLocale, CurrentLocale()); - pref_service_->SetInteger(prefs::kSystemWebAppInstallFailureCount, 0); + pref_service_->SetInteger(::prefs::kSystemWebAppInstallFailureCount, 0); // Report install duration only if the install pipeline actually installs // all the apps (e.g. on version upgrade). @@ -594,10 +600,10 @@ RecordSystemWebAppInstallResults(install_results); for (const auto& it : system_app_delegates_) { - absl::optional<ash::SystemWebAppBackgroundTaskInfo> background_info = + absl::optional<SystemWebAppBackgroundTaskInfo> background_info = it.second->GetTimerInfo(); if (background_info && it.second->IsAppEnabled()) { - tasks_.push_back(std::make_unique<ash::SystemWebAppBackgroundTask>( + tasks_.push_back(std::make_unique<SystemWebAppBackgroundTask>( profile_, background_info.value())); } } @@ -628,17 +634,17 @@ } bool SystemWebAppManager::ShouldForceInstallApps() const { - if (base::FeatureList::IsEnabled(features::kAlwaysReinstallSystemWebApps)) + if (base::FeatureList::IsEnabled(::features::kAlwaysReinstallSystemWebApps)) return true; if (update_policy_ == UpdatePolicy::kAlwaysUpdate) return true; base::Version current_installed_version( - pref_service_->GetString(prefs::kSystemWebAppLastUpdateVersion)); + pref_service_->GetString(::prefs::kSystemWebAppLastUpdateVersion)); const std::string& current_installed_locale( - pref_service_->GetString(prefs::kSystemWebAppLastInstalledLocale)); + pref_service_->GetString(::prefs::kSystemWebAppLastInstalledLocale)); // If Chrome version rolls back for some reason, ensure System Web Apps are // always in sync with Chrome version. @@ -654,32 +660,32 @@ void SystemWebAppManager::UpdateLastAttemptedInfo() { base::Version last_attempted_version( - pref_service_->GetString(prefs::kSystemWebAppLastAttemptedVersion)); + pref_service_->GetString(::prefs::kSystemWebAppLastAttemptedVersion)); const std::string& last_attempted_locale( - pref_service_->GetString(prefs::kSystemWebAppLastAttemptedLocale)); + pref_service_->GetString(::prefs::kSystemWebAppLastAttemptedLocale)); const bool is_retry = last_attempted_version.IsValid() && last_attempted_version == CurrentVersion() && last_attempted_locale == CurrentLocale(); if (!is_retry) { - pref_service_->SetInteger(prefs::kSystemWebAppInstallFailureCount, 0); + pref_service_->SetInteger(::prefs::kSystemWebAppInstallFailureCount, 0); } - pref_service_->SetString(prefs::kSystemWebAppLastAttemptedVersion, + pref_service_->SetString(::prefs::kSystemWebAppLastAttemptedVersion, CurrentVersion().GetString()); - pref_service_->SetString(prefs::kSystemWebAppLastAttemptedLocale, + pref_service_->SetString(::prefs::kSystemWebAppLastAttemptedLocale, CurrentLocale()); pref_service_->CommitPendingWrite(); } bool SystemWebAppManager::CheckAndIncrementRetryAttempts() { int installation_failures = - pref_service_->GetInteger(prefs::kSystemWebAppInstallFailureCount); + pref_service_->GetInteger(::prefs::kSystemWebAppInstallFailureCount); bool reached_retry_limit = installation_failures > kInstallFailureAttempts; if (!reached_retry_limit) { - pref_service_->SetInteger(prefs::kSystemWebAppInstallFailureCount, + pref_service_->SetInteger(::prefs::kSystemWebAppInstallFailureCount, installation_failures + 1); pref_service_->CommitPendingWrite(); return false; @@ -687,4 +693,4 @@ return true; } -} // namespace web_app +} // namespace ash
diff --git a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.h b/chrome/browser/ash/system_web_apps/system_web_app_manager.h similarity index 77% rename from chrome/browser/web_applications/system_web_apps/system_web_app_manager.h rename to chrome/browser/ash/system_web_apps/system_web_app_manager.h index 45fd326..1c101233 100644 --- a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.h +++ b/chrome/browser/ash/system_web_apps/system_web_app_manager.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_ -#define CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_ +#ifndef CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_ +#define CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_ #include <map> #include <memory> @@ -42,14 +42,16 @@ class PrefRegistrySyncable; } -class PrefService; -class Profile; - namespace web_app { - class WebAppUiManager; class WebAppSyncBridge; class WebAppPolicyManager; +} // namespace web_app + +class PrefService; +class Profile; + +namespace ash { // Installs, uninstalls, and updates System Web Apps. // System Web Apps are built-in, highly-privileged Web Apps for Chrome OS. They @@ -70,7 +72,7 @@ "Webapp.SystemApps.FreshInstallDuration"; // Returns whether the given app type is enabled. - bool IsAppEnabled(ash::SystemWebAppType type) const; + bool IsAppEnabled(SystemWebAppType type) const; explicit SystemWebAppManager(Profile* profile); SystemWebAppManager(const SystemWebAppManager&) = delete; @@ -96,11 +98,11 @@ static SystemWebAppManager* GetForTest(Profile* profile); void SetSubsystems( - ExternallyManagedAppManager* externally_managed_app_manager, - WebAppRegistrar* registrar, - WebAppSyncBridge* sync_bridge, - WebAppUiManager* ui_manager, - WebAppPolicyManager* web_app_policy_manager); + web_app::ExternallyManagedAppManager* externally_managed_app_manager, + web_app::WebAppRegistrar* registrar, + web_app::WebAppSyncBridge* sync_bridge, + web_app::WebAppUiManager* ui_manager, + web_app::WebAppPolicyManager* web_app_policy_manager); void Start(); @@ -118,30 +120,30 @@ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); // Returns the app id for the given System App |type|. - absl::optional<AppId> GetAppIdForSystemApp(ash::SystemWebAppType type) const; + absl::optional<web_app::AppId> GetAppIdForSystemApp( + SystemWebAppType type) const; // Returns the System App Type for the given |app_id|. - absl::optional<ash::SystemWebAppType> GetSystemAppTypeForAppId( - const AppId& app_id) const; + absl::optional<SystemWebAppType> GetSystemAppTypeForAppId( + const web_app::AppId& app_id) const; // Returns the System App Delegate for the given App |type|. - const ash::SystemWebAppDelegate* GetSystemApp( - ash::SystemWebAppType type) const; + const SystemWebAppDelegate* GetSystemApp(SystemWebAppType type) const; // Returns the App Ids for all installed System Web Apps. - std::vector<AppId> GetAppIds() const; + std::vector<web_app::AppId> GetAppIds() const; // Returns whether |app_id| points to an installed System App. - bool IsSystemWebApp(const AppId& app_id) const; + bool IsSystemWebApp(const web_app::AppId& app_id) const; // Perform tab-specific setup when a navigation in a System Web App is about // to be committed. - void OnReadyToCommitNavigation(const AppId& app_id, + void OnReadyToCommitNavigation(const web_app::AppId& app_id, content::NavigationHandle* navigation_handle); - // Returns the ash::SystemWebAppType that should capture the navigation to + // Returns the SystemWebAppType that should capture the navigation to // |url|. - absl::optional<ash::SystemWebAppType> GetCapturingSystemAppForURL( + absl::optional<SystemWebAppType> GetCapturingSystemAppForURL( const GURL& url) const; const base::OneShotEvent& on_apps_synchronized() const { @@ -156,13 +158,13 @@ // Returns a map of registered system app types and infos, these apps will be // installed on the system. - const ash::SystemWebAppDelegateMap& system_app_delegates() const { + const SystemWebAppDelegateMap& system_app_delegates() const { return system_app_delegates_; } // This call will override default System Apps configuration. You should call // Start() after this call to install |system_apps|. - void SetSystemAppsForTesting(ash::SystemWebAppDelegateMap system_apps); + void SetSystemAppsForTesting(SystemWebAppDelegateMap system_apps); // Overrides the update policy. If AlwaysReinstallSystemWebApps feature is // enabled, this method does nothing, and system apps will be reinstalled. @@ -173,7 +175,7 @@ void Shutdown(); // Get the timers. Only use this for testing. - const std::vector<std::unique_ptr<ash::SystemWebAppBackgroundTask>>& + const std::vector<std::unique_ptr<SystemWebAppBackgroundTask>>& GetBackgroundTasksForTesting(); const Profile* profile() const { return profile_; } @@ -187,7 +189,7 @@ // App |type|. Returns an empty vector if the App does not specify origin // trials for |url|. const std::vector<std::string>* GetEnabledOriginTrials( - const ash::SystemWebAppDelegate* system_app, + const SystemWebAppDelegate* system_app, const GURL& url) const; void StopBackgroundTasks(); @@ -195,7 +197,7 @@ void OnAppsSynchronized( bool did_force_install_apps, const base::TimeTicks& install_start_time, - std::map<GURL, ExternallyManagedAppManager::InstallResult> + std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult> install_results, std::map<GURL, bool> uninstall_results); bool ShouldForceInstallApps() const; @@ -205,7 +207,7 @@ bool CheckAndIncrementRetryAttempts(); void RecordSystemWebAppInstallResults( - const std::map<GURL, ExternallyManagedAppManager::InstallResult>& + const std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult>& install_results) const; void RecordSystemWebAppInstallDuration( @@ -224,27 +226,27 @@ UpdatePolicy update_policy_; - ash::SystemWebAppDelegateMap system_app_delegates_; + SystemWebAppDelegateMap system_app_delegates_; const raw_ptr<PrefService> pref_service_; // Used to install, uninstall, and update apps. Should outlive this class. - raw_ptr<ExternallyManagedAppManager> externally_managed_app_manager_ = - nullptr; + raw_ptr<web_app::ExternallyManagedAppManager> + externally_managed_app_manager_ = nullptr; - raw_ptr<WebAppRegistrar> registrar_ = nullptr; + raw_ptr<web_app::WebAppRegistrar> registrar_ = nullptr; - raw_ptr<WebAppSyncBridge> sync_bridge_ = nullptr; + raw_ptr<web_app::WebAppSyncBridge> sync_bridge_ = nullptr; - raw_ptr<WebAppUiManager> ui_manager_ = nullptr; + raw_ptr<web_app::WebAppUiManager> ui_manager_ = nullptr; - raw_ptr<WebAppPolicyManager> web_app_policy_manager_ = nullptr; + raw_ptr<web_app::WebAppPolicyManager> web_app_policy_manager_ = nullptr; - std::vector<std::unique_ptr<ash::SystemWebAppBackgroundTask>> tasks_; + std::vector<std::unique_ptr<SystemWebAppBackgroundTask>> tasks_; base::WeakPtrFactory<SystemWebAppManager> weak_ptr_factory_{this}; }; -} // namespace web_app +} // namespace ash -#endif // CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_ +#endif // CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_
diff --git a/chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_delegate.cc b/chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_delegate.cc index 424dff27..09208c6 100644 --- a/chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_delegate.cc +++ b/chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_delegate.cc
@@ -22,8 +22,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/ash/file_manager/path_util.h" -#include "chrome/browser/web_applications/web_app_tab_helper.h" -// TODO(b/174811949): Hide behind ChromeOS build flag. +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_constants.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" @@ -31,7 +30,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_launch_queue.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -200,7 +198,7 @@ file_manager::util::GetMyFilesFolderForProfile(profile); absl::optional<web_app::AppId> app_id = - web_app::SystemWebAppManager::Get(profile)->GetAppIdForSystemApp( + ash::SystemWebAppManager::Get(profile)->GetAppIdForSystemApp( ash::SystemWebAppType::CAMERA); // The launch directory is passed here rather than
diff --git a/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc index 89c51caa..5b692ea 100644 --- a/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc
@@ -6,11 +6,11 @@ #include "ash/webui/diagnostics_ui/url_constants.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ash/web_applications/eche_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/eche_app_integration_browsertest.cc index a2632e1..5bfd6d3 100644 --- a/chrome/browser/ash/web_applications/eche_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/eche_app_integration_browsertest.cc
@@ -6,13 +6,13 @@ #include "ash/shell.h" #include "ash/webui/eche_app_ui/url_constants.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/screen.h"
diff --git a/chrome/browser/ash/web_applications/firmware_update_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/firmware_update_app_integration_browsertest.cc index 0594a48..6a5cb55 100644 --- a/chrome/browser/ash/web_applications/firmware_update_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/firmware_update_app_integration_browsertest.cc
@@ -5,9 +5,9 @@ #include "ash/webui/firmware_update_ui/url_constants.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "components/webapps/browser/install_result_code.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ash/web_applications/help_app/help_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/help_app/help_app_integration_browsertest.cc index b6224762..d5ffc718 100644 --- a/chrome/browser/ash/web_applications/help_app/help_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/help_app/help_app_integration_browsertest.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/ash/release_notes/release_notes_notification.h" #include "chrome/browser/ash/release_notes/release_notes_storage.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/help_app/help_app_discover_tab_notification.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/notifications/notification_display_service_tester.h" @@ -38,7 +39,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -694,7 +694,7 @@ // Wait for system apps background tasks to start. base::RunLoop run_loop; - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->on_tasks_started() .Post(FROM_HERE, run_loop.QuitClosure()); run_loop.Run();
diff --git a/chrome/browser/ash/web_applications/media_app/media_app_guest_ui_config.cc b/chrome/browser/ash/web_applications/media_app/media_app_guest_ui_config.cc index d100ab8..f71b9bde 100644 --- a/chrome/browser/ash/web_applications/media_app/media_app_guest_ui_config.cc +++ b/chrome/browser/ash/web_applications/media_app/media_app_guest_ui_config.cc
@@ -8,12 +8,17 @@ #include "ash/constants/ash_features.h" #include "ash/webui/media_app_ui/url_constants.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/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/common/channel_info.h" #include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" #include "components/prefs/pref_service.h" +#include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/types_util.h" #include "components/version_info/channel.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -27,6 +32,15 @@ content::WebUIDataSource* source) { Profile* profile = Profile::FromWebUI(web_ui); PrefService* pref_service = profile->GetPrefs(); + apps::AppRegistryCache& app_registry_cache = + apps::AppServiceProxyFactory::GetForProfile(profile)->AppRegistryCache(); + + bool photosInstalled = false; + app_registry_cache.ForOneApp( + arc::kGooglePhotosAppId, + [&photosInstalled](const apps::AppUpdate& update) { + photosInstalled = apps_util::IsInstalled(update.Readiness()); + }); source->AddString("appLocale", g_browser_process->GetApplicationLocale()); source->AddBoolean("pdfInInk", base::FeatureList::IsEnabled( @@ -42,6 +56,7 @@ version_info::Channel channel = chrome::GetChannel(); source->AddBoolean("colorThemes", chromeos::features::IsDarkLightModeEnabled()); + source->AddBoolean("photosAvailable", photosInstalled); source->AddBoolean("flagsMenu", channel != version_info::Channel::BETA && channel != version_info::Channel::STABLE); source->AddBoolean("isDevChannel", channel == version_info::Channel::DEV);
diff --git a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc index e6ffe0c..17030007 100644 --- a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/ash/file_manager/app_id.h" #include "chrome/browser/ash/file_manager/app_service_file_tasks.h" #include "chrome/browser/ash/file_manager/file_manager_test_util.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/media_app/media_web_app_info.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/error_reporting/mock_chrome_js_error_report_processor.h" @@ -36,7 +37,6 @@ #include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/common/chrome_paths.h" #include "chromeos/constants/chromeos_features.h"
diff --git a/chrome/browser/ash/web_applications/os_feedback_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/os_feedback_app_integration_browsertest.cc index be72546..133d3e8 100644 --- a/chrome/browser/ash/web_applications/os_feedback_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/os_feedback_app_integration_browsertest.cc
@@ -8,13 +8,13 @@ #include "ash/webui/sample_system_web_app_ui/url_constants.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/interactive_test_utils.h"
diff --git a/chrome/browser/ash/web_applications/print_management_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/print_management_app_integration_browsertest.cc index 6d620f4..5bbed68 100644 --- a/chrome/browser/ash/web_applications/print_management_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/print_management_app_integration_browsertest.cc
@@ -4,7 +4,6 @@ #include "ash/webui/print_management/url_constants.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ash/web_applications/sample_system_web_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/sample_system_web_app_integration_browsertest.cc index c561dbc..9cb4264 100644 --- a/chrome/browser/ash/web_applications/sample_system_web_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/sample_system_web_app_integration_browsertest.cc
@@ -3,8 +3,8 @@ // found in the LICENSE file. #include "ash/webui/sample_system_web_app_ui/url_constants.h" +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc index d74ad456..13dbdbc 100644 --- a/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/scanning_app_integration_browsertest.cc
@@ -4,10 +4,10 @@ #include "ash/webui/scanning/url_constants.h" #include "base/values.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/policy/system_features_disable_list_policy_handler.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/test/base/testing_browser_process.h" #include "components/policy/core/common/policy_pref_names.h" #include "components/prefs/scoped_user_pref_update.h"
diff --git a/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc index ac412446..dc0f2e5 100644 --- a/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/settings_app_integration_browsertest.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/policy/system_features_disable_list_policy_handler.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/test/base/testing_browser_process.h" #include "components/policy/core/common/policy_pref_names.h" #include "components/prefs/scoped_user_pref_update.h" @@ -64,7 +64,7 @@ // This test verifies that the settings page is opened in a new browser window. IN_PROC_BROWSER_TEST_P(SettingsAppIntegrationTest, OmniboxNavigateToSettings) { // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); GURL old_url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL(); { @@ -94,7 +94,7 @@ RedirectIncognitoToOriginalProfile) { // Install the real SWA, not the test mock. This verifies the production // SystemAppInfo is correct. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); // When launching from incognito profile, OS Settings gets launched to the
diff --git a/chrome/browser/ash/web_applications/shimless_rma_integration_browsertest.cc b/chrome/browser/ash/web_applications/shimless_rma_integration_browsertest.cc index a266577..5d38a82 100644 --- a/chrome/browser/ash/web_applications/shimless_rma_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/shimless_rma_integration_browsertest.cc
@@ -8,7 +8,6 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "components/webapps/browser/install_result_code.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc index 2ff9d7bde..83992055 100644 --- a/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/shortcut_customization_app_integration_browsertest.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/ash/web_applications/system_web_app_integration_test.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "components/webapps/browser/install_result_code.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_navigation_observer.h"
diff --git a/chrome/browser/ash/web_applications/system_web_app_integration_test.cc b/chrome/browser/ash/web_applications/system_web_app_integration_test.cc index 48b16ac..28a0821 100644 --- a/chrome/browser/ash/web_applications/system_web_app_integration_test.cc +++ b/chrome/browser/ash/web_applications/system_web_app_integration_test.cc
@@ -6,12 +6,12 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/apps/app_service/app_launch_params.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "content/public/browser/web_ui.h" #include "content/public/test/test_navigation_observer.h"
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index 2fc7ad6c..acf5f89 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -1646,7 +1646,7 @@ EXPECT_EQ("Milton", GetFieldValue(GetElementById("firstname"))); } -// Test that an input field is not rendered with the yellow autofilled +// Test that an input field is not rendered with the blue autofilled // background color when choosing an option from the datalist suggestion list. IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, OnSelectOptionFromDatalist) { static const char kTestForm[] =
diff --git a/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc b/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc index 3884318..61fdc65 100644 --- a/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc +++ b/chrome/browser/autofill_assistant/password_change/apc_client_impl.cc
@@ -8,10 +8,12 @@ #include <string> #include "base/bind.h" +#include "base/feature_list.h" #include "base/memory/raw_ptr.h" #include "chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/autofill_assistant/password_change/assistant_display_delegate.h" +#include "chrome/browser/ui/ui_features.h" #include "content/public/browser/web_contents.h" #include "url/gurl.h" @@ -23,6 +25,11 @@ bool ApcClientImpl::Start(const GURL& url, const std::string& username, bool skip_login) { + // If the unified side panel is not enabled, trying to register an entry in it + // later on will crash. + if (!base::FeatureList::IsEnabled(features::kUnifiedSidePanel)) + return false; + // Ensure that only one run is ongoing. if (is_running_) return false;
diff --git a/chrome/browser/autofill_assistant/password_change/apc_client_impl_unittest.cc b/chrome/browser/autofill_assistant/password_change/apc_client_impl_unittest.cc index 96188b12..8b38d24 100644 --- a/chrome/browser/autofill_assistant/password_change/apc_client_impl_unittest.cc +++ b/chrome/browser/autofill_assistant/password_change/apc_client_impl_unittest.cc
@@ -6,8 +6,10 @@ #include "base/memory/raw_ptr.h" #include "base/test/gmock_move_support.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/autofill_assistant/password_change/apc_onboarding_coordinator_impl.h" #include "chrome/browser/autofill_assistant/password_change/mock_apc_onboarding_coordinator.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_task_environment.h" @@ -59,6 +61,7 @@ public: ApcClientImplTest() : web_contents_(web_contents_factory_.CreateWebContents(&profile_)) { + feature_list_.InitWithFeatures({features::kUnifiedSidePanel}, {}); // Make sure that a `TestApcClientImpl` is registered for that // `WebContents`. test_apc_client_ = TestApcClientImpl::CreateForWebContents(web_contents()); @@ -70,6 +73,7 @@ private: // Supporting members to create the testing environment. content::BrowserTaskEnvironment task_environment_; + base::test::ScopedFeatureList feature_list_; TestingProfile profile_; content::TestWebContentsFactory web_contents_factory_; raw_ptr<content::WebContents> web_contents_; @@ -109,3 +113,20 @@ std::move(coordinator_callback).Run(false); EXPECT_FALSE(client->IsRunning()); } + +TEST_F(ApcClientImplTest, CreateAndStartApcFlow_WithUnifiedSidePanelDisabled) { + base::test::ScopedFeatureList override_feature_list; + override_feature_list.InitWithFeatures({}, {features::kUnifiedSidePanel}); + raw_ptr<ApcClient> client = + ApcClient::GetOrCreateForWebContents(web_contents()); + + // There is one client per WebContents. + EXPECT_EQ(client, apc_client()); + + // The `ApcClient` is paused. + EXPECT_FALSE(client->IsRunning()); + + // Starting it does not work. + EXPECT_FALSE(client->Start(GURL(kUrl1), kUsername1, /*skip_login=*/true)); + EXPECT_FALSE(client->IsRunning()); +}
diff --git a/chrome/browser/autofill_assistant/password_change/apc_external_action_delegate.h b/chrome/browser/autofill_assistant/password_change/apc_external_action_delegate.h index 2b567e45..3615032 100644 --- a/chrome/browser/autofill_assistant/password_change/apc_external_action_delegate.h +++ b/chrome/browser/autofill_assistant/password_change/apc_external_action_delegate.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_AUTOFILL_ASSISTANT_PASSWORD_CHANGE_APC_EXTERNAL_ACTION_DELEGATE_H_ #define CHROME_BROWSER_AUTOFILL_ASSISTANT_PASSWORD_CHANGE_APC_EXTERNAL_ACTION_DELEGATE_H_ +#include "chrome/browser/ui/autofill_assistant/password_change/password_change_run_controller.h" #include "components/autofill_assistant/browser/public/external_action_delegate.h" class ApcExternalActionDelegate @@ -24,6 +25,10 @@ result)> end_action_callback) override; void OnInterruptStarted() override; void OnInterruptFinished() override; + + private: + // Stores the UI state of a password change run. + PasswordChangeRunController::Model model_; }; #endif // CHROME_BROWSER_AUTOFILL_ASSISTANT_PASSWORD_CHANGE_APC_EXTERNAL_ACTION_DELEGATE_H_
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 1fe7d66..f7a4bbfe 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -538,11 +538,11 @@ frame_host->GetProcess()->GetBrowserContext()); if (captions::IsLiveCaptionFeatureSupported()) { #if BUILDFLAG(ENABLE_BROWSER_SPEECH_SERVICE) - SpeechRecognitionServiceFactory::GetForProfile(profile)->Create( - std::move(receiver)); + SpeechRecognitionServiceFactory::GetForProfile(profile) + ->BindSpeechRecognitionContext(std::move(receiver)); #elif BUILDFLAG(IS_CHROMEOS_ASH) - CrosSpeechRecognitionServiceFactory::GetForProfile(profile)->Create( - std::move(receiver)); + CrosSpeechRecognitionServiceFactory::GetForProfile(profile) + ->BindSpeechRecognitionContext(std::move(receiver)); #elif BUILDFLAG(IS_CHROMEOS_LACROS) // TODO(b:223493879): Provide LaCrOS implementation, via go/crosapi. #error "LaCrOS speech recognition service factory not implemented yet."
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 69ab674..bc30618 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -441,7 +441,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/search/new_tab_page_navigation_throttle.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h"
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 541c1af..78ce7c4d 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -100,6 +100,7 @@ #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/settings/stats_reporting_controller.h" #include "chrome/browser/ash/system/input_device_settings.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/banners/app_banner_manager_desktop.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" @@ -131,7 +132,6 @@ #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h" #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h" #include "chrome/browser/web_applications/app_registrar_observer.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/common/extensions/api/autotest_private.h" @@ -373,10 +373,9 @@ case apps::AppType::kStandaloneBrowserExtension: return api::autotest_private::AppType::APP_TYPE_NONE; case apps::AppType::kStandaloneBrowserChromeApp: - // Intentionally fall-through for now. // TODO(https://crbug.com/1225848): Figure out appropriate behavior for // Lacros-hosted chrome-apps. - break; + return api::autotest_private::AppType::APP_TYPE_NONE; } NOTREACHED(); return api::autotest_private::AppType::APP_TYPE_NONE; @@ -2085,8 +2084,8 @@ ExtensionFunction::ResponseAction AutotestPrivateWaitForSystemWebAppsInstallFunction::Run() { Profile* profile = Profile::FromBrowserContext(browser_context()); - web_app::SystemWebAppManager* swa_manager = - web_app::SystemWebAppManager::GetForTest(profile); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::GetForTest(profile); if (!swa_manager) return RespondNow(Error("System Web Apps are not available for profile.")); @@ -2112,8 +2111,8 @@ ExtensionFunction::ResponseAction AutotestPrivateGetRegisteredSystemWebAppsFunction::Run() { Profile* profile = Profile::FromBrowserContext(browser_context()); - web_app::SystemWebAppManager* swa_manager = - web_app::SystemWebAppManager::GetForTest(profile); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::GetForTest(profile); if (!swa_manager) return RespondNow(Error("System Web Apps are not available for profile.")); @@ -2229,8 +2228,8 @@ << params->app_name << " url: " << params->url; Profile* profile = Profile::FromBrowserContext(browser_context()); - web_app::SystemWebAppManager* swa_manager = - web_app::SystemWebAppManager::GetForTest(profile); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::GetForTest(profile); if (!swa_manager) return RespondNow(Error("System Web Apps not enabled for profile."));
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc index 3187c3c..8ff64deeb 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/ash/file_manager/filesystem_api_util.h" #include "chrome/browser/chromeos/fileapi/file_system_backend.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/extensions/api/file_manager_private.h"
diff --git a/chrome/browser/chromeos/extensions/install_limiter.h b/chrome/browser/chromeos/extensions/install_limiter.h index 2328951e..457140a 100644 --- a/chrome/browser/chromeos/extensions/install_limiter.h +++ b/chrome/browser/chromeos/extensions/install_limiter.h
@@ -20,11 +20,6 @@ namespace extensions { -// TODO(hendrich, https://crbug.com/1046302) -// Add a test for the InstallLimiter, which checks that small extensions are -// installed before large extensions and that we don't have to wait the entire -// 5s when the OnAllExternalProvidersReady() signal was called. - // InstallLimiter defers big app installs after all small app installs and then // runs big app installs one by one. This improves first-time login experience. // See http://crbug.com/166296
diff --git a/chrome/browser/chromeos/extensions/install_limiter_unittest.cc b/chrome/browser/chromeos/extensions/install_limiter_unittest.cc index 6929dfdc..8fb840d 100644 --- a/chrome/browser/chromeos/extensions/install_limiter_unittest.cc +++ b/chrome/browser/chromeos/extensions/install_limiter_unittest.cc
@@ -5,34 +5,59 @@ #include "chrome/browser/chromeos/extensions/install_limiter.h" #include "ash/components/tpm/stub_install_attributes.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" #include "chrome/browser/ash/login/demo_mode/demo_mode_test_helper.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/extensions/crx_installer.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_service_test_base.h" #include "components/user_manager/scoped_user_manager.h" +#include "content/public/browser/notification_service.h" #include "content/public/test/browser_task_environment.h" +#include "extensions/browser/crx_file_info.h" #include "extensions/common/constants.h" +#include "extensions/common/extension.h" +#include "extensions/common/verifier_formats.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using extensions::InstallLimiter; +using testing::Field; +using testing::Invoke; +using testing::Mock; namespace { constexpr char kRandomExtensionId[] = "abacabadabacabaeabacabadabacabaf"; + constexpr int kLargeExtensionSize = 2000000; constexpr int kSmallExtensionSize = 200000; +constexpr char kLargeExtensionCrx[] = "large.crx"; +constexpr char kSmallExtensionCrx[] = "small.crx"; + +constexpr base::TimeDelta kLessThanExpectedWaitTime = base::Seconds(4); +constexpr base::TimeDelta kTimeDeltaUntilExpectedWaitTime = base::Seconds(1); + } // namespace -class InstallLimiterTest +class InstallLimiterShouldDeferInstallTest : public testing::TestWithParam<ash::DemoSession::DemoModeConfig> { public: - InstallLimiterTest() + InstallLimiterShouldDeferInstallTest() : scoped_user_manager_(std::make_unique<ash::FakeChromeUserManager>()) {} - InstallLimiterTest(const InstallLimiterTest&) = delete; - InstallLimiterTest& operator=(const InstallLimiterTest&) = delete; + InstallLimiterShouldDeferInstallTest( + const InstallLimiterShouldDeferInstallTest&) = delete; + InstallLimiterShouldDeferInstallTest& operator=( + const InstallLimiterShouldDeferInstallTest&) = delete; - ~InstallLimiterTest() override = default; + ~InstallLimiterShouldDeferInstallTest() override = default; private: content::BrowserTaskEnvironment task_environment_; @@ -40,7 +65,7 @@ user_manager::ScopedUserManager scoped_user_manager_; }; -TEST_P(InstallLimiterTest, ShouldDeferInstall) { +TEST_P(InstallLimiterShouldDeferInstallTest, ShouldDeferInstall) { const std::vector<std::string> screensaver_ids = { extension_misc::kScreensaverAppId, extension_misc::kScreensaverAtlasAppId, extension_misc::kScreensaverKraneZdksAppId}; @@ -66,6 +91,175 @@ INSTANTIATE_TEST_SUITE_P( DemoModeConfig, - InstallLimiterTest, + InstallLimiterShouldDeferInstallTest, ::testing::Values(ash::DemoSession::DemoModeConfig::kNone, ash::DemoSession::DemoModeConfig::kOnline)); + +namespace extensions { + +// A mock around CrxInstaller to track extension installations. +class MockCrxInstaller : public CrxInstaller { + public: + explicit MockCrxInstaller(ExtensionService* frontend) + : CrxInstaller(frontend->AsWeakPtr(), nullptr, nullptr) {} + + MOCK_METHOD(void, InstallCrxFile, (const CRXFileInfo& source_file)); + + private: + ~MockCrxInstaller() override = default; +}; + +} // namespace extensions + +class InstallLimiterTest : public extensions::ExtensionServiceTestBase { + public: + InstallLimiterTest() + : extensions::ExtensionServiceTestBase( + std::make_unique<content::BrowserTaskEnvironment>( + base::test::TaskEnvironment::MainThreadType::IO, + content::BrowserTaskEnvironment::TimeSource::MOCK_TIME)) {} + + InstallLimiterTest(const InstallLimiterTest&) = delete; + InstallLimiterTest& operator=(const InstallLimiterTest&) = delete; + + ~InstallLimiterTest() override = default; + + void NotifyCrxInstallerDone() { + content::NotificationService::current()->Notify( + extensions::NOTIFICATION_CRX_INSTALLER_DONE, + content::Source<extensions::MockCrxInstaller>(mock_installer_.get()), + content::Details<const extensions::Extension>(NULL)); + } + + protected: + void SetUp() override { + extensions::ExtensionServiceTestBase::SetUp(); + + extensions::ExtensionServiceTestBase::ExtensionServiceInitParams params = + CreateDefaultInitParams(); + params.enable_install_limiter = true; + InitializeExtensionService(params); + + install_limiter_ = InstallLimiter::Get(profile()); + + mock_installer_ = + base::MakeRefCounted<extensions::MockCrxInstaller>(service()); + } + + extensions::CRXFileInfo CreateTestExtensionCrx(const base::FilePath& path, + int extension_size) { + const std::string data(extension_size, 0); + EXPECT_TRUE(base::WriteFile(path, data)); + extensions::CRXFileInfo crx_info(path, extensions::GetTestVerifierFormat()); + crx_info.extension_id = kRandomExtensionId; + return crx_info; + } + + InstallLimiter* install_limiter_; + scoped_refptr<extensions::MockCrxInstaller> mock_installer_; +}; + +// Test that small extensions are installed immediately. +TEST_F(InstallLimiterTest, DontDeferSmallExtensionInstallation) { + const base::FilePath path = + extensions_install_dir().AppendASCII(kSmallExtensionCrx); + extensions::CRXFileInfo crx_info_small = + CreateTestExtensionCrx(path, kSmallExtensionSize); + + EXPECT_CALL(*mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, path))); + install_limiter_->Add(mock_installer_, crx_info_small); + task_environment()->RunUntilIdle(); + Mock::VerifyAndClearExpectations(mock_installer_.get()); +} + +// Test that large extension installations are deferred. +TEST_F(InstallLimiterTest, DeferLargeExtensionInstallation) { + const base::FilePath path = + extensions_install_dir().AppendASCII(kLargeExtensionCrx); + extensions::CRXFileInfo crx_info_large = + CreateTestExtensionCrx(path, kLargeExtensionSize); + + // Check that the large extension will not be installed immediately. + EXPECT_CALL(*mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, path))) + .Times(0); + install_limiter_->Add(mock_installer_, crx_info_large); + task_environment()->FastForwardBy(kLessThanExpectedWaitTime); + task_environment()->RunUntilIdle(); + Mock::VerifyAndClearExpectations(mock_installer_.get()); + + // The installation starts only after the wait time is elapsed. + EXPECT_CALL(*mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, path))); + task_environment()->FastForwardBy(kTimeDeltaUntilExpectedWaitTime); + task_environment()->RunUntilIdle(); + Mock::VerifyAndClearExpectations(mock_installer_.get()); +} + +// Test that deferred installations are run before the wait time expires if the +// OnAllExternalProvidersReady() signal was called. +TEST_F(InstallLimiterTest, RunDeferredInstallsWhenAllExternalProvidersReady) { + const base::FilePath path = + extensions_install_dir().AppendASCII(kLargeExtensionCrx); + extensions::CRXFileInfo crx_info_large = + CreateTestExtensionCrx(path, kLargeExtensionSize); + + // Check that the large extension will not be installed immediately. + EXPECT_CALL(*mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, path))) + .Times(0); + install_limiter_->Add(mock_installer_, crx_info_large); + task_environment()->FastForwardBy(kLessThanExpectedWaitTime); + task_environment()->RunUntilIdle(); + Mock::VerifyAndClearExpectations(mock_installer_.get()); + + // The installation starts before the wait time is elapsed if + // OnAllExternalProvidersReady() is called. + EXPECT_CALL(*mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, path))); + install_limiter_->OnAllExternalProvidersReady(); + task_environment()->RunUntilIdle(); + Mock::VerifyAndClearExpectations(mock_installer_.get()); +} + +// Test that small extensions are installed before large extensions. +TEST_F(InstallLimiterTest, InstallSmallBeforeLargeExtensions) { + // Create a large test extension crx file. + const base::FilePath crx_path_large = + extensions_install_dir().AppendASCII(kLargeExtensionCrx); + extensions::CRXFileInfo crx_info_large = + CreateTestExtensionCrx(crx_path_large, kLargeExtensionSize); + + // Create a small test extension crx file. + const base::FilePath crx_path_small = + extensions_install_dir().AppendASCII(kSmallExtensionCrx); + extensions::CRXFileInfo crx_info_small = + CreateTestExtensionCrx(crx_path_small, kSmallExtensionSize); + + base::RunLoop run_loop; + + // When adding a large extension and then a small extension, the small + // extension will be installed first. The mock function call will trigger a + // CRX_INSTALLER_DONE notification which will notify the install limiter to + // continue with any deferred installations. This will then start the + // installation of the large extension. + { + testing::InSequence s; + + EXPECT_CALL( + *mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, crx_path_small))) + .WillOnce(Invoke(this, &InstallLimiterTest::NotifyCrxInstallerDone)); + EXPECT_CALL( + *mock_installer_, + InstallCrxFile(Field(&extensions::CRXFileInfo::path, crx_path_large))) + .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)); + } + + install_limiter_->Add(mock_installer_, crx_info_large); + install_limiter_->Add(mock_installer_, crx_info_small); + run_loop.Run(); + + Mock::VerifyAndClearExpectations(mock_installer_.get()); +}
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc index 9a20e45..c36dac9 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_converters_unittest.cc
@@ -44,7 +44,10 @@ kName, telemetry_service::UInt64Value::New(kTimeInStateSinceLastBootUs)); auto result = ConvertPtr<telemetry_api::CpuCStateInfo>(std::move(input)); + ASSERT_TRUE(result.name); EXPECT_EQ(kName, *result.name); + + ASSERT_TRUE(result.time_in_state_since_last_boot_us); EXPECT_EQ(kTimeInStateSinceLastBootUs, *result.time_in_state_since_last_boot_us); } @@ -70,15 +73,27 @@ std::move(expected_c_states)); auto result = ConvertPtr<telemetry_api::LogicalCpuInfo>(std::move(input)); + ASSERT_TRUE(result.max_clock_speed_khz); EXPECT_EQ(kMaxClockSpeedKhz, static_cast<uint32_t>(*result.max_clock_speed_khz)); + + ASSERT_TRUE(result.scaling_max_frequency_khz); EXPECT_EQ(kScalingMaxFrequencyKhz, static_cast<uint32_t>(*result.scaling_max_frequency_khz)); + + ASSERT_TRUE(result.scaling_current_frequency_khz); EXPECT_EQ(kScalingCurrentFrequencyKhz, static_cast<uint32_t>(*result.scaling_current_frequency_khz)); + + ASSERT_TRUE(result.idle_time_ms); EXPECT_EQ(kIdleTime, *result.idle_time_ms); + EXPECT_EQ(1u, result.c_states.size()); + + ASSERT_TRUE(result.c_states[0].name); EXPECT_EQ(kCpuCStateName, *result.c_states[0].name); + + ASSERT_TRUE(result.c_states[0].time_in_state_since_last_boot_us); EXPECT_EQ(kCpuCStateTime, *result.c_states[0].time_in_state_since_last_boot_us); } @@ -110,19 +125,35 @@ std::move(logical_cpus)); auto result = ConvertPtr<telemetry_api::PhysicalCpuInfo>(std::move(input)); + ASSERT_TRUE(result.model_name); EXPECT_EQ(kModelName, *result.model_name); + EXPECT_EQ(1u, result.logical_cpus.size()); + + ASSERT_TRUE(result.logical_cpus[0].max_clock_speed_khz); EXPECT_EQ(kMaxClockSpeedKhz, static_cast<uint32_t>(*result.logical_cpus[0].max_clock_speed_khz)); + + ASSERT_TRUE(result.logical_cpus[0].scaling_max_frequency_khz); EXPECT_EQ( kScalingMaxFrequencyKhz, static_cast<uint32_t>(*result.logical_cpus[0].scaling_max_frequency_khz)); + + ASSERT_TRUE(result.logical_cpus[0].scaling_current_frequency_khz); EXPECT_EQ(kScalingCurrentFrequencyKhz, static_cast<uint32_t>( *result.logical_cpus[0].scaling_current_frequency_khz)); + + ASSERT_TRUE(result.logical_cpus[0].idle_time_ms); EXPECT_EQ(kIdleTime, *result.logical_cpus[0].idle_time_ms); + EXPECT_EQ(1u, result.logical_cpus[0].c_states.size()); + + ASSERT_TRUE(result.logical_cpus[0].c_states[0].name); EXPECT_EQ(kCpuCStateName, *result.logical_cpus[0].c_states[0].name); + + ASSERT_TRUE( + result.logical_cpus[0].c_states[0].time_in_state_since_last_boot_us); EXPECT_EQ( kCpuCStateTime, *result.logical_cpus[0].c_states[0].time_in_state_since_last_boot_us); @@ -155,22 +186,47 @@ kManufacturerDate, telemetry_service::UInt64Value::New(kTemperature)); auto result = ConvertPtr<telemetry_api::BatteryInfo>(std::move(input)); + ASSERT_TRUE(result.cycle_count); EXPECT_EQ(kCycleCount, static_cast<int64_t>(*result.cycle_count)); + + ASSERT_TRUE(result.voltage_now); EXPECT_EQ(kVoltageNow, static_cast<double_t>(*result.voltage_now)); + + ASSERT_TRUE(result.vendor); EXPECT_EQ(kVendor, *result.vendor); // serial_number is not converted in ConvertPtr(). EXPECT_TRUE(result.serial_number == nullptr); + + ASSERT_TRUE(result.charge_full_design); EXPECT_EQ(kChargeFullDesign, static_cast<double_t>(*result.charge_full_design)); + + ASSERT_TRUE(result.charge_full); EXPECT_EQ(kChargeFull, static_cast<double_t>(*result.charge_full)); + + ASSERT_TRUE(result.voltage_min_design); EXPECT_EQ(kVoltageMinDesign, static_cast<double_t>(*result.voltage_min_design)); + + ASSERT_TRUE(result.model_name); EXPECT_EQ(kModelName, *result.model_name); + + ASSERT_TRUE(result.charge_now); EXPECT_EQ(kChargeNow, static_cast<double_t>(*result.charge_now)); + + ASSERT_TRUE(result.current_now); EXPECT_EQ(kCurrentNow, static_cast<double_t>(*result.current_now)); + + ASSERT_TRUE(result.technology); EXPECT_EQ(kTechnology, *result.technology); + + ASSERT_TRUE(result.status); EXPECT_EQ(kStatus, *result.status); + + ASSERT_TRUE(result.manufacture_date); EXPECT_EQ(kManufacturerDate, *result.manufacture_date); + + ASSERT_TRUE(result.temperature); EXPECT_EQ(kTemperature, static_cast<uint64_t>(*result.temperature)); }
diff --git a/chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part_browsertest.cc b/chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part_browsertest.cc index 6a53ba5..5acb865 100644 --- a/chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part_browsertest.cc +++ b/chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part_browsertest.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" @@ -20,7 +20,7 @@ IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientTabletModePartTest, SettingsWindowFontSize) { // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); const blink::web_pref::WebPreferences kDefaultPrefs;
diff --git a/chrome/browser/component_updater/app_provisioning_component_installer.cc b/chrome/browser/component_updater/app_provisioning_component_installer.cc index e1df56a..06b121f5 100644 --- a/chrome/browser/component_updater/app_provisioning_component_installer.cc +++ b/chrome/browser/component_updater/app_provisioning_component_installer.cc
@@ -12,6 +12,7 @@ #include <utility> #include <vector> +#include "ash/constants/ash_features.h" #include "base/bind.h" #include "base/callback.h" #include "base/feature_list.h" @@ -143,7 +144,8 @@ } void RegisterAppProvisioningComponent(component_updater::ComponentUpdateService* cus) { - if (!base::FeatureList::IsEnabled(features::kAppProvisioningStatic)) { + if (!base::FeatureList::IsEnabled(features::kAppProvisioningStatic) || + !ash::features::IsCloudGamingDevice()) { return; }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc index c4f8aea..d0542706 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc
@@ -598,10 +598,6 @@ failures_.insert({std::move(path), std::move(response)}); } - void SetPathIsEncrypted(base::FilePath path) { - encrypted_.insert(std::move(path)); - } - void SetScanPolicies(bool dlp, bool malware) { include_dlp_ = dlp; include_malware_ = malware; @@ -639,9 +635,6 @@ base::BindRepeating( &ContentAnalysisDelegateAuditOnlyTest::ConnectorStatusCallback, base::Unretained(this)), - base::BindRepeating( - &ContentAnalysisDelegateAuditOnlyTest::EncryptionStatusCallback, - base::Unretained(this)), kDmToken)); } @@ -667,10 +660,6 @@ return response; } - bool EncryptionStatusCallback(const base::FilePath& path) { - return encrypted_.count(path) > 0; - } - private: ScopedSetDMToken scoped_dm_token_{ policy::DMToken::CreateValidTokenForTesting(kDmToken)}; @@ -681,10 +670,6 @@ // The actual failure response is given for each path. std::map<base::FilePath, ContentAnalysisResponse> failures_; - // Paths in this set will be considered to contain encryption and will - // not be uploaded. - std::set<base::FilePath> encrypted_; - // DLP response to ovewrite in the callback if present. absl::optional<ContentAnalysisResponse> dlp_response_ = absl::nullopt; }; @@ -1622,8 +1607,6 @@ base::BindRepeating( &ContentAnalysisDelegateResultHandlingTest::ConnectorStatusCallback, base::Unretained(this)), - /*encryption_callback=*/ - base::BindRepeating([](const base::FilePath& path) { return false; }), kDmToken)); }
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc index c4cf5114..29023b4f 100644 --- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc
@@ -26,7 +26,6 @@ FakeContentAnalysisDelegate::FakeContentAnalysisDelegate( base::RepeatingClosure delete_closure, StatusCallback status_callback, - EncryptionStatusCallback encryption_callback, std::string dm_token, content::WebContents* web_contents, Data data, @@ -37,7 +36,6 @@ safe_browsing::DeepScanAccessPoint::UPLOAD), delete_closure_(delete_closure), status_callback_(status_callback), - encryption_callback_(encryption_callback), dm_token_(std::move(dm_token)) {} FakeContentAnalysisDelegate::~FakeContentAnalysisDelegate() { @@ -55,14 +53,13 @@ std::unique_ptr<ContentAnalysisDelegate> FakeContentAnalysisDelegate::Create( base::RepeatingClosure delete_closure, StatusCallback status_callback, - EncryptionStatusCallback encryption_callback, std::string dm_token, content::WebContents* web_contents, Data data, CompletionCallback callback) { auto ret = std::make_unique<FakeContentAnalysisDelegate>( - delete_closure, status_callback, encryption_callback, std::move(dm_token), - web_contents, std::move(data), std::move(callback)); + delete_closure, status_callback, std::move(dm_token), web_contents, + std::move(data), std::move(callback)); return ret; }
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h index 61f46712..7290d35 100644 --- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h +++ b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h
@@ -33,14 +33,8 @@ base::RepeatingCallback<enterprise_connectors::ContentAnalysisResponse( const base::FilePath&)>; - // Callback that determines the encryption of the file specified. Returns - // true if the file is considered encrypted for tests. - using EncryptionStatusCallback = - base::RepeatingCallback<bool(const base::FilePath&)>; - FakeContentAnalysisDelegate(base::RepeatingClosure delete_closure, StatusCallback status_callback, - EncryptionStatusCallback encryption_callback, std::string dm_token, content::WebContents* web_contents, Data data, @@ -53,7 +47,6 @@ static std::unique_ptr<ContentAnalysisDelegate> Create( base::RepeatingClosure delete_closure, StatusCallback status_callback, - EncryptionStatusCallback encryption_callback, std::string dm_token, content::WebContents* web_contents, Data data, @@ -113,7 +106,6 @@ static safe_browsing::BinaryUploadService::Result result_; base::RepeatingClosure delete_closure_; StatusCallback status_callback_; - EncryptionStatusCallback encryption_callback_; std::string dm_token_; base::WeakPtrFactory<FakeContentAnalysisDelegate> weakptr_factory_{this};
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc index 62aca9e2..c6b11621 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -683,6 +683,9 @@ ExtensionFunction::ResponseAction TerminalPrivateGetOSInfoFunction::Run() { base::DictionaryValue info; + info.SetBoolKey( + "multi_profile", + base::FeatureList::IsEnabled(chromeos::features::kTerminalMultiProfile)); info.SetBoolKey("tmux_integration", base::FeatureList::IsEnabled( chromeos::features::kTerminalTmuxIntegration));
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 608e0d9..5a50106 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h
@@ -44,6 +44,7 @@ class ExtensionService; class ExtensionUpdaterTest; enum class InstallationStage; +class MockCrxInstaller; class PreloadCheckGroup; // This class installs a crx file into a profile. @@ -119,7 +120,7 @@ void InstallCrx(const base::FilePath& source_file); // Install the crx in |source_file|. - void InstallCrxFile(const CRXFileInfo& source_file); + virtual void InstallCrxFile(const CRXFileInfo& source_file); // Install the unpacked crx in |unpacked_dir|. // If |delete_source_| is true, |unpacked_dir| will be removed at the end of @@ -262,6 +263,7 @@ friend class ::ExtensionServiceTest; friend class BookmarkAppInstallFinalizerTest; friend class ExtensionUpdaterTest; + friend class MockCrxInstaller; CrxInstaller(base::WeakPtr<ExtensionService> service_weak, std::unique_ptr<ExtensionInstallPrompt> client,
diff --git a/chrome/browser/extensions/extension_service_test_base.cc b/chrome/browser/extensions/extension_service_test_base.cc index c10561b..2276c5d 100644 --- a/chrome/browser/extensions/extension_service_test_base.cc +++ b/chrome/browser/extensions/extension_service_test_base.cc
@@ -412,7 +412,8 @@ service_->shared_module_service()); #if BUILDFLAG(IS_CHROMEOS_ASH) - InstallLimiter::Get(profile())->DisableForTest(); + if (!params.enable_install_limiter) + InstallLimiter::Get(profile())->DisableForTest(); #endif }
diff --git a/chrome/browser/extensions/extension_service_test_base.h b/chrome/browser/extensions/extension_service_test_base.h index ff00127..0e29bec 100644 --- a/chrome/browser/extensions/extension_service_test_base.h +++ b/chrome/browser/extensions/extension_service_test_base.h
@@ -70,6 +70,7 @@ bool profile_is_supervised = false; bool profile_is_guest = false; bool enable_bookmark_model = false; + bool enable_install_limiter = false; raw_ptr<policy::PolicyService> policy_service = nullptr;
diff --git a/chrome/browser/feedback/show_feedback_page_browsertest.cc b/chrome/browser/feedback/show_feedback_page_browsertest.cc index 4decdb0..09c5ac8 100644 --- a/chrome/browser/feedback/show_feedback_page_browsertest.cc +++ b/chrome/browser/feedback/show_feedback_page_browsertest.cc
@@ -5,12 +5,12 @@ #include "ash/constants/ash_features.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" @@ -59,7 +59,7 @@ // opened and the os_feedback is used when the feature kOsFeedback is enabled. IN_PROC_BROWSER_TEST_F(ShowFeedbackPageBrowserTest, OsFeedbackIsOpenedWhenFeatureEnabled) { - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); base::HistogramTester histogram_tester;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 0f78329..f391c47 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -5281,7 +5281,12 @@ { "name": "sanitizer-api", "owners": [ "//third_party/blink/renderer/modules/sanitizer_api/OWNERS" ], - "expiry_milestone": 105 + "expiry_milestone": 109 + }, + { + "name": "sanitizer-api-v0", + "owners": [ "//third_party/blink/renderer/modules/sanitizer_api/OWNERS" ], + "expiry_milestone": 109 }, { "name": "scheduler-configuration", @@ -5796,6 +5801,11 @@ "expiry_milestone": -1 }, { + "name": "terminal-multi-profile", + "owners": [ "joelhockey", "lxj", "//chrome/browser/ash/guest_os/OWNERS" ], + "expiry_milestone": 120 + }, + { "name": "terminal-tmux-integration", "owners": [ "lxj", "easy", "//chrome/browser/ash/guest_os/OWNERS" ], "expiry_milestone": 106
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b3088d8..667c38c 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2945,6 +2945,12 @@ const char kSanitizerApiDescription[] = "Enable the Sanitizer API. See: https://github.com/WICG/sanitizer-api"; +const char kSanitizerApiv0Name[] = "Sanitizer API, Initial version"; +const char kSanitizerApiv0Description[] = + "Enable the initial version of the Sanitizer API. This includes the " + "Element.setHTML method, but not any sanitization methods on the " + "Sanitizer instances. See also the #sanitizer-api flag."; + const char kUsePassthroughCommandDecoderName[] = "Use passthrough command decoder"; const char kUsePassthroughCommandDecoderDescription[] = @@ -5436,6 +5442,11 @@ "Enables Terminal System App to load from Downloads for developer testing. " "Only works in dev and canary channels."; +const char kTerminalMultiProfileName[] = "Terminal multi-profiles for settings"; +const char kTerminalMultiProfileDescription[] = + "Enables Terminal System App to set multiple profiles in the settings page " + "and configure which profile to use for each Linux or SSH connection."; + const char kTerminalTmuxIntegrationName[] = "Terminal tmux integration"; const char kTerminalTmuxIntegrationDescription[] = "Enables integration with tmux control mode (tmux -CC) in the Terminal "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 9cc988b..a542f480 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1660,6 +1660,9 @@ extern const char kSanitizerApiName[]; extern const char kSanitizerApiDescription[]; +extern const char kSanitizerApiv0Name[]; +extern const char kSanitizerApiv0Description[]; + extern const char kUsePassthroughCommandDecoderName[]; extern const char kUsePassthroughCommandDecoderDescription[]; @@ -3107,6 +3110,9 @@ extern const char kTerminalDevName[]; extern const char kTerminalDevDescription[]; +extern const char kTerminalMultiProfileName[]; +extern const char kTerminalMultiProfileDescription[]; + extern const char kTerminalTmuxIntegrationName[]; extern const char kTerminalTmuxIntegrationDescription[];
diff --git a/chrome/browser/incognito/android/java/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthDialog.java b/chrome/browser/incognito/android/java/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthDialog.java index 30b5b26..835213c 100644 --- a/chrome/browser/incognito/android/java/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthDialog.java +++ b/chrome/browser/incognito/android/java/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthDialog.java
@@ -35,18 +35,16 @@ IncognitoReauthDialog( @NonNull ModalDialogManager modalDialogManager, @NonNull View incognitoReauthView) { mModalDialogManager = modalDialogManager; - // TODO(crbug.com/1227656): Add support for high dialog priority and dialog styling. mModalDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) .with(ModalDialogProperties.CONTROLLER, mController) .with(ModalDialogProperties.CUSTOM_VIEW, incognitoReauthView) .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, false) .with(ModalDialogProperties.FULLSCREEN_DIALOG, true) + .with(ModalDialogProperties.EXCEED_MAX_HEIGHT, true) .build(); } void showIncognitoReauthDialog(boolean showFullScreen) { - // TODO(crbug.com/1227656): Tab based re-auth dialog doesn't work as they - // get dismissed by {@link TabModalLifetimeHandler}. mModalDialogManager.showDialog(mModalDialogModel, (showFullScreen) ? ModalDialogManager.ModalDialogType.APP : ModalDialogManager.ModalDialogType.TAB);
diff --git a/chrome/browser/password_manager/password_scripts_fetcher_factory.cc b/chrome/browser/password_manager/password_scripts_fetcher_factory.cc index dedccf7b..51ef901 100644 --- a/chrome/browser/password_manager/password_scripts_fetcher_factory.cc +++ b/chrome/browser/password_manager/password_scripts_fetcher_factory.cc
@@ -62,6 +62,9 @@ } return new password_manager::PasswordScriptsFetcherImpl( - version_info::GetVersion(), browser_context->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess()); + std::make_unique<autofill_assistant::CommonDependenciesChrome>() + ->IsSupervisedUser(browser_context), + version_info::GetVersion(), + browser_context->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess()); }
diff --git a/chrome/browser/policy/test/system_features_policy_browsertest.cc b/chrome/browser/policy/test/system_features_policy_browsertest.cc index 0ba8d2cb..bd67a61 100644 --- a/chrome/browser/policy/test/system_features_policy_browsertest.cc +++ b/chrome/browser/policy/test/system_features_policy_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.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/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/policy/policy_test_utils.h" @@ -16,7 +17,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -139,7 +139,7 @@ } void InstallSWAs() { - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); }
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 336f8af..87df3b0 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -757,6 +757,11 @@ "arc.native_bridge_64bit_support_experiment"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(ENABLE_DICE_SUPPORT) +// Deprecated 06/2022. +const char kTokenServiceDiceCompatible[] = "token_service.dice_compatible"; +#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -994,6 +999,10 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) registry->RegisterBooleanPref(kColorModeThemed, true); #endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + registry->RegisterBooleanPref(kTokenServiceDiceCompatible, false); +#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) } } // namespace @@ -1941,6 +1950,11 @@ profile_prefs->ClearPref(kColorModeThemed); #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + // Added 06/2022. + profile_prefs->ClearPref(kTokenServiceDiceCompatible); +#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_PROFILE_PREFS
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc index 53abbfe..e9c7565 100644 --- a/chrome/browser/printing/print_browsertest.cc +++ b/chrome/browser/printing/print_browsertest.cc
@@ -3492,11 +3492,6 @@ base::BindRepeating( &ContentAnalysisPrintBrowserTest::ScanningResponse, base::Unretained(this)), - /*file_encrypted=*/ - base::BindRepeating([](const base::FilePath& path) { - NOTREACHED(); - return false; - }), kFakeDmToken)); feature_list_.InitAndEnableFeature(features::kEnablePrintContentAnalysis);
diff --git a/chrome/browser/privacy_budget/identifiability_study_state.cc b/chrome/browser/privacy_budget/identifiability_study_state.cc index fff1ed9..15f8d98 100644 --- a/chrome/browser/privacy_budget/identifiability_study_state.cc +++ b/chrome/browser/privacy_budget/identifiability_study_state.cc
@@ -80,6 +80,10 @@ if (LIKELY(!settings_.enabled())) return false; + // We always record surfaces of type zero. + if (surface.GetType() == blink::IdentifiableSurface::Type::kReservedInternal) + return true; + if (base::Contains(active_surfaces_, surface)) return true; @@ -577,6 +581,12 @@ blink::IdentifiableSurface::Type::kMeasuredSurface)) { return false; } + + if (surface.GetType() == + blink::IdentifiableSurface::Type::kReservedInternal) { + return false; + } + return surface_encounters_.IsNewEncounter(source_id, surface.ToUkmMetricHash()); }
diff --git a/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc b/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc index edc27fe..10ec320 100644 --- a/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc +++ b/chrome/browser/privacy_budget/identifiability_study_state_unittest.cc
@@ -723,6 +723,90 @@ EXPECT_LE(selected_surfaces, kMaxSelectedSurfaces); } +TEST(IdentifiabilityStudyStateStandaloneTest, + AlwaysSampleReservedInternalRandom) { + test::ScopedPrivacyBudgetConfig::Parameters parameters; + parameters.active_surface_budget = kTestingActiveSurfaceBudget; + parameters.expected_surface_count = 20; + parameters.allowed_random_types = { + blink::IdentifiableSurface::Type::kWebFeature}; + test::ScopedPrivacyBudgetConfig config(parameters); + + TestingPrefServiceSimple pref_service; + prefs::RegisterPrivacyBudgetPrefs(pref_service.registry()); + test_utils::InspectableIdentifiabilityStudyState state(&pref_service); + + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsCrossOriginFrame)))); + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsCrossSiteFrame)))); + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsMainFrame)))); + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_NavigationSourceId)))); +} + +TEST(IdentifiabilityStudyStateStandaloneTest, + AlwaysSampleReservedInternalBlock) { + const int kTestGroupCount = 80; + const int kSurfacesInGroup = 40; + + test::ScopedPrivacyBudgetConfig::Parameters parameters; + for (int group_index = 0; group_index < kTestGroupCount; ++group_index) { + parameters.blocks.emplace_back( + CreateSurfaceList(kSurfacesInGroup, kSurfacesInGroup * group_index)); + } + + parameters.block_weights.assign(kTestGroupCount, 1.0); + parameters.active_surface_budget = kSurfacesInGroup; + test::ScopedPrivacyBudgetConfig config(parameters); + + TestingPrefServiceSimple pref_service; + prefs::RegisterPrivacyBudgetPrefs(pref_service.registry()); + test_utils::InspectableIdentifiabilityStudyState state(&pref_service); + + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsCrossOriginFrame)))); + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsCrossSiteFrame)))); + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsMainFrame)))); + EXPECT_TRUE( + state.ShouldRecordSurface(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableToken( + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_NavigationSourceId)))); +} + TEST(IdentifiabilityStudyStateStandaloneTest, NoAllowedTypes) { constexpr auto kExpectedSurfaceCount = 20;
diff --git a/chrome/browser/privacy_budget/privacy_budget_browsertest.cc b/chrome/browser/privacy_budget/privacy_budget_browsertest.cc index 47bd50c..75cc99c 100644 --- a/chrome/browser/privacy_budget/privacy_budget_browsertest.cc +++ b/chrome/browser/privacy_budget/privacy_budget_browsertest.cc
@@ -12,6 +12,7 @@ #include <utility> #include <vector> +#include "base/barrier_closure.h" #include "base/containers/flat_map.h" #include "base/feature_list.h" #include "base/logging.h" @@ -176,8 +177,13 @@ : public PrivacyBudgetBrowserTestWithScopedConfig { public: void SetUpOnMainThread() override { - ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>(); PrivacyBudgetBrowserTestBase::SetUpOnMainThread(); + // Do an initial empty navigation then create the recorder to make sure we + // start on a clean slate. This clears the platform differences in between + // Android and Desktop. + content::NavigateToURLBlockUntilNavigationsComplete(web_contents(), + GURL("about:blank"), 1); + ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>(); } ukm::TestUkmRecorder& recorder() { return *ukm_recorder_; } @@ -218,8 +224,11 @@ content::DOMMessageQueue messages(web_contents()); base::RunLoop run_loop; + // We expect 3 entries here generated by the two navigations from the test. + // The first navigation adds a document created entry and a web feature entry, + // while the second one generates only a document created entry. recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName, - run_loop.QuitClosure()); + BarrierClosure(3u, run_loop.QuitClosure())); ASSERT_TRUE(content::NavigateToURL( web_contents(), embedded_test_server()->GetURL( @@ -245,14 +254,23 @@ auto merged_entries = recorder().GetMergedEntriesByName( ukm::builders::Identifiability::kEntryName); - // Shouldn't be more than one source here. If this changes, then we'd need to - // adjust this test to deal. - ASSERT_EQ(1u, merged_entries.size()); + + // We expect two merged entries, corresponding to the two navigations. + ASSERT_EQ(merged_entries.size(), 2u); + + // We collect all metrics together and check that there is one that contains + // the web feature metrics. + auto it = merged_entries.begin(); + auto metrics = it->second->metrics; + + for (auto& it : merged_entries) { + metrics.insert(it.second->metrics.begin(), it.second->metrics.end()); + } // All of the following features should be included in the list of returned // metrics here. The exact values depend on the test host. EXPECT_THAT( - merged_entries.begin()->second->metrics, + metrics, IsSupersetOf({ Key(HashFeature( blink::mojom::WebFeature::kV8Screen_Height_AttributeGetter)), @@ -268,14 +286,88 @@ } IN_PROC_BROWSER_TEST_F(PrivacyBudgetBrowserTestWithTestRecorder, + EveryNavigationRecordsDocumentCreatedMetrics) { + ASSERT_TRUE(embedded_test_server()->Start()); + + content::DOMMessageQueue messages(web_contents()); + base::RunLoop run_loop; + + // We expect 3 entries here generated by the two navigations from the test. + // The first navigation adds a document created entry and a web feature entry, + // while the second one generates only a document created entry. + recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName, + BarrierClosure(3u, run_loop.QuitClosure())); + + ASSERT_TRUE(content::NavigateToURL( + web_contents(), embedded_test_server()->GetURL( + "/privacy_budget/samples_screen_attributes.html"))); + + // The document calls a bunch of instrumented functions and sends a message + // back to the test. Receipt of the message indicates that the script + // successfully completed. + std::string screen_scrape; + ASSERT_TRUE(messages.WaitForMessage(&screen_scrape)); + + // The contents of the received message isn't used for anything other than + // diagnostics. + SCOPED_TRACE(screen_scrape); + + // Navigating away from the test page causes the document to be unloaded. That + // will cause any buffered metrics to be flushed. + content::NavigateToURLBlockUntilNavigationsComplete(web_contents(), + GURL("about:blank"), 1); + + // Wait for the metrics to come down the pipe. + run_loop.Run(); + + auto merged_entries = recorder().GetMergedEntriesByName( + ukm::builders::Identifiability::kEntryName); + + // We expect two merged entries, corresponding to the two navigations. + ASSERT_EQ(merged_entries.size(), 2u); + + // Each entry in merged_entries corresponds to a committed navigation and they + // all should contain the document created metrics. + for (auto& it : merged_entries) { + EXPECT_THAT(it.second->metrics, + IsSupersetOf({ + Key(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsMainFrame) + .ToUkmMetricHash()), + Key(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsCrossOriginFrame) + .ToUkmMetricHash()), + Key(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_IsCrossSiteFrame) + .ToUkmMetricHash()), + Key(blink::IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + blink::IdentifiableSurface::ReservedSurfaceMetrics:: + kDocumentCreated_NavigationSourceId) + .ToUkmMetricHash()), + })); + } +} + +IN_PROC_BROWSER_TEST_F(PrivacyBudgetBrowserTestWithTestRecorder, CallsCanvasToBlob) { ASSERT_TRUE(embedded_test_server()->Start()); content::DOMMessageQueue messages(web_contents()); base::RunLoop run_loop; + // We expect 3 entries here generated by the two navigations + // from the test. The first navigation adds a document created entry and a web + // feature entry, while the second one generates only a document created + // entry. recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName, - run_loop.QuitClosure()); + BarrierClosure(3u, run_loop.QuitClosure())); ASSERT_TRUE(content::NavigateToURL( web_contents(), embedded_test_server()->GetURL( @@ -299,14 +391,26 @@ auto merged_entries = recorder().GetMergedEntriesByName( ukm::builders::Identifiability::kEntryName); - // Shouldn't be more than one source here. If this changes, then we'd need to - // adjust this test to deal. - ASSERT_EQ(1u, merged_entries.size()); + + // We expect two merged entries, corresponding to the two navigations. + ASSERT_EQ(merged_entries.size(), 2u); // toBlob() is called on a context-less canvas, hence -1, which is the value // of blink::CanvasRenderingContext::CanvasRenderingAPI::kUnknown. constexpr uint64_t input_digest = -1; - EXPECT_THAT(merged_entries.begin()->second->metrics, + + // We collect all metrics together and check that there is one that contains + // the canvas readback metrics. + auto it = merged_entries.begin(); + auto metrics = it->second->metrics; + + for (auto& it : merged_entries) { + metrics.insert(it.second->metrics.begin(), it.second->metrics.end()); + } + + // The exact values depend on the test host, so we only check that the metric + // was collected. + EXPECT_THAT(metrics, IsSupersetOf({ Key(blink::IdentifiableSurface::FromTypeAndToken( blink::IdentifiableSurface::Type::kCanvasReadback, @@ -329,8 +433,12 @@ content::DOMMessageQueue messages(web_contents()); base::RunLoop run_loop; + // We expect 3 entries here generated by the two navigations + // from the test. The first navigation adds a document created entry and a web + // feature entry, while the second one generates only a document created + // entry. recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName, - run_loop.QuitClosure()); + BarrierClosure(3u, run_loop.QuitClosure())); ASSERT_TRUE(content::NavigateToURL( web_contents(), embedded_test_server()->GetURL( @@ -354,17 +462,26 @@ auto merged_entries = recorder().GetMergedEntriesByName( ukm::builders::Identifiability::kEntryName); - // Shouldn't be more than one source here. If this changes, then we'd need to - // adjust this test to deal. - ASSERT_EQ(1u, merged_entries.size()); - auto& metrics = merged_entries.begin()->second->metrics; + // We expect two merged entries, corresponding to the two navigations. + ASSERT_EQ(merged_entries.size(), 2u); // (kCanvasReadback | input_digest << kTypeBits) = one of the merged_entries // If the value of the relevant merged entry changes, input_digest needs to // change. The new input_digest can be calculated by: - // new_input_digest = new_ukm_entry >> kTypeBits + // new_input_digest = new_ukm_entry >> kTypeBits; constexpr uint64_t input_digest = UINT64_C(33457614533296512); + // We collect all metrics together and check that there is one that contains + // the canvas readback metrics. + auto it = merged_entries.begin(); + auto metrics = it->second->metrics; + + for (auto& it : merged_entries) { + metrics.insert(it.second->metrics.begin(), it.second->metrics.end()); + } + + // The exact values depend on the test host, so we only check that the metric + // was collected. EXPECT_THAT(metrics, IsSupersetOf({ Key(blink::IdentifiableSurface::FromTypeAndToken( @@ -381,10 +498,8 @@ } } -// TODO(crbug.com/1268787): Test has been broken on Windows CI since it was -// first landed. IN_PROC_BROWSER_TEST_F(PrivacyBudgetBrowserTestWithScopedConfig, - DISABLED_IncludesMetadata) { + IncludesMetadata) { ASSERT_TRUE(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy)); ASSERT_TRUE(EnableUkmRecording()); @@ -402,6 +517,7 @@ ukm::UkmTestHelper ukm_test_helper(ukm_service()); ukm_test_helper.BuildAndStoreLog(); std::unique_ptr<ukm::Report> ukm_report = ukm_test_helper.GetUkmReport(); + ASSERT_TRUE(ukm_test_helper.HasUnsentLogs()); ASSERT_TRUE(ukm_report); ASSERT_NE(ukm_report->entries_size(), 0);
diff --git a/chrome/browser/privacy_sandbox/android/java/res/layout/privacy_sandbox_notice_bottom_sheet.xml b/chrome/browser/privacy_sandbox/android/java/res/layout/privacy_sandbox_notice_bottom_sheet.xml index 8ca452e..1b77c89 100644 --- a/chrome/browser/privacy_sandbox/android/java/res/layout/privacy_sandbox_notice_bottom_sheet.xml +++ b/chrome/browser/privacy_sandbox/android/java/res/layout/privacy_sandbox_notice_bottom_sheet.xml
@@ -39,10 +39,10 @@ style="@style/TextAppearance.Headline.Primary" /> <TextView + android:id="@+id/privacy_sandbox_notice_sheet_description" android:layout_marginBottom="@dimen/list_item_default_margin" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/privacy_sandbox_notice_sheet_description" style="@style/TextAppearance.TextLarge.Secondary" /> <LinearLayout
diff --git a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBottomSheetNotice.java b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBottomSheetNotice.java index 7c2affb..fafc929 100644 --- a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBottomSheetNotice.java +++ b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBottomSheetNotice.java
@@ -5,8 +5,10 @@ package org.chromium.chrome.browser.privacy_sandbox; import android.content.Context; +import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; +import android.widget.TextView; import androidx.annotation.Nullable; @@ -15,6 +17,9 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; import org.chromium.components.browser_ui.settings.SettingsLauncher; +import org.chromium.ui.text.NoUnderlineClickableSpan; +import org.chromium.ui.text.SpanApplier; +import org.chromium.ui.text.SpanApplier.SpanInfo; /** Bottom sheet view for displaying the Privacy Sandbox notice. */ public class PrivacySandboxBottomSheetNotice implements BottomSheetContent { @@ -55,6 +60,17 @@ } }; + TextView description = + mContentView.findViewById(R.id.privacy_sandbox_notice_sheet_description); + description.setText(SpanApplier.applySpans( + context.getString(R.string.privacy_sandbox_notice_sheet_description), + new SpanInfo( + "<link>", "</link>", new NoUnderlineClickableSpan(context, (widget) -> { + mSettingsLauncher.launchSettingsActivity( + context, LearnMoreFragment.class); + })))); + description.setMovementMethod(LinkMovementMethod.getInstance()); + View ackButton = mContentView.findViewById(R.id.ack_button); ackButton.setOnClickListener((v) -> { mBottomSheetController.hideContent(this, /* animate= */ true,
diff --git a/chrome/browser/profiles/profile_metrics.h b/chrome/browser/profiles/profile_metrics.h index 92af418d8..9a223d4 100644 --- a/chrome/browser/profiles/profile_metrics.h +++ b/chrome/browser/profiles/profile_metrics.h
@@ -70,7 +70,9 @@ kAbortedBeforeSignIn = 10, kAbortedAfterSignIn = 11, kAbortedOnEnterpriseWelcome = 12, - kMaxValue = kAbortedOnEnterpriseWelcome, + kSkippedAlreadySyncing = 13, + kSkippedByPolicies = 14, + kMaxValue = kSkippedByPolicies, }; // These values are persisted to logs. Entries should not be renumbered and
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 5523ec4c..9d871de 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/apps/app_service/browser_app_launcher.h" #include "chrome/browser/apps/platform_apps/app_load_service.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h" +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" #include "chrome/browser/browser_features.h" #include "chrome/browser/browser_process.h" @@ -95,7 +96,6 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/webui/history/foreign_session_handler.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_icon_manager.h"
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/settings_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/settings_test.js index 260f77ea..19088c7e 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/settings_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/settings_test.js
@@ -15,7 +15,7 @@ testGenCppIncludes() { super.testGenCppIncludes(); GEN(` - #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" + #include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" `); } @@ -23,7 +23,7 @@ /** @override */ testGenPreamble() { GEN(` - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); `); super.testGenPreamble();
diff --git a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn index 877235f..d72d07d 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn +++ b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
@@ -15,7 +15,6 @@ "emoji_picker.js", "emoji_search.js", "emoji_variants.js", - "emoticon_group.js", "icons.js", "text_group_button.js", ] @@ -196,7 +195,6 @@ ":emoji_group_button", ":emoji_picker_api_proxy", ":emoji_search", - ":emoticon_group", ":events", ":store", ":text_group_button", @@ -266,13 +264,6 @@ externs_list = [ "//ui/webui/resources/cr_elements/cr_search_field/cr_search_field_externs.js" ] } -js_library("emoticon_group") { - deps = [ - ":types", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} - js_library("icons") { deps = [ "//third_party/polymer/v3_0/components-chromium/iron-iconset-svg", @@ -329,7 +320,6 @@ ":emoji_picker_api_proxy", ":emoji_search", ":emoji_variants", - ":emoticon_group", ":events", ":icons", ":store",
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html index b8451fc..af5762a2 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_button.html
@@ -1,26 +1,17 @@ <style> :host { --emoji-background: transparent; - height: var(--emoji-size); + /* Fixed height and width are required for buttons that have variants, + * Otherwise, when showing variants, buttons' positions will be moved. + */ + height: var(--emoji-button-height); position: relative; - width: var(--emoji-size); + width: var(--emoji-button-width); } #emoji-button { - background: var(--emoji-background); - border: none; - border-radius: 50%; - cursor: pointer; - display: block; - font-family: 'Noto Color Emoji'; - font-size: 19px; /*This gives emoji with height of 22px*/ - height: 100%; - line-height: var(--emoji-size); - outline: none; - padding: 0; - text-align: center; - user-select: none; - width: 100%; + /* TODO(b/233130994): Remove this CSS mixin and use classes instead. */ + @apply --emoji-button-button-style; } #emoji-button:focus, @@ -65,12 +56,12 @@ #tooltip { --paper-tooltip-background: var(--cros-tooltip-background-color); - --paper-tooltip-opacity: 1; - --paper-tooltip-text-color: var(--cros-tooltip-label-color); --paper-tooltip-delay-in: var(--emoji-tooltip-delay-in); --paper-tooltip-delay-out: var(--emoji-tooltip-delay-out); --paper-tooltip-duration-in: 0; --paper-tooltip-duration-out: 0; + --paper-tooltip-opacity: 1; + --paper-tooltip-text-color: var(--cros-tooltip-label-color); } #tooltip::part(tooltip) { @@ -83,14 +74,9 @@ } </style> - -<button - id="emoji-button" - class$="[[_className(variants)]]" - on-click="onClick" - on-contextmenu="onContextMenu" - disabled="[[disabled]]" - aria-label="[[_label(tooltip, emoji, variants)]]"> +<button id="emoji-button" class$="[[_className(variants)]]" + on-click="onClick" on-contextmenu="onContextMenu" + disabled="[[disabled]]" aria-label="[[_label(tooltip, emoji, variants)]]"> [[emoji]] </button> <template is="dom-if" if="[[!variant]]"> @@ -98,8 +84,8 @@ part="tooltip" offset="8"> [[tooltip]] </paper-tooltip> -</tooltip> +</template> <template is="dom-if" if="[[variantsVisible]]"> <emoji-variants variants="[[variants]]" tooltip="[[tooltip]]"> </emoji-variants> -</template> +</template> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_button.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_button.js index 81947db..3e9752d 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_button.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_button.js
@@ -37,6 +37,12 @@ allVariants: {type: Array, readonly: true}, /** @type {!string} */ tooltip: {type: String, readonly: true}, + /** @type {string} */ + category: { + type: String, + value: CategoryEnum.EMOJI, + readonly: true, + }, }; } @@ -62,7 +68,7 @@ baseEmoji: this.base, allVariants: this.allVariants ? this.allVariants : this.variants, name: this.tooltip, - category: CategoryEnum.EMOJI, + category: this.category, })); }
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html index 3458bbbb..8e93f84 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html
@@ -4,13 +4,80 @@ position: relative; } + + :host([v2-enabled]:not([use-flex-layout])) { + --emoji-size: var(--v2-emoji-size); + --emoji-spacing: var(--v2-emoji-spacing); + } + + /* TODO(b/233268914): Allow adding per emoji category style. + * The refactor should make setting styles per emoji category + * (e.g. emoji, emoticon, symbol) easy. Also, base styles need to be + * defined for common parts of different emoji categories styles. + */ + + /* Grid layout styles. */ + :host(:not([use-flex-layout])) #emoji { + display: grid; + gap: var(--emoji-spacing); + grid-auto-rows: max-content; + grid-template-columns: repeat(var(--emoji-per-row), 1fr); + justify-items: center; + } + + :host(:not([use-flex-layout])) emoji-button { + --emoji-button-button-style: { + background: var(--emoji-background); + border: none; + border-radius: 50%; + cursor: pointer; + display: block; + font-family: 'Noto Color Emoji'; + font-size: 19px; + height: 100%; + line-height: var(--emoji-size); + outline: none; + padding: 0; + text-align: center; + user-select: none; + width: 100%; + }; + --emoji-button-height: var(--emoji-size); + --emoji-button-width: var(--emoji-size); + } + + /* Flex layout styles. */ + :host([use-flex-layout]) #emoji { + display: flex; + flex-wrap: wrap; + gap: 12px 20px; + } + + :host([use-flex-layout]) emoji-button { + --emoji-button-button-style: { + background: var(--emoji-background); + border: none; + color: var(--cros-text-color-primary); + cursor: pointer; + font-family: 'Noto Sans CJK JP'; + font-size: 13px; + height: 100%; + padding: 6px; + width: max-content; + }; + --emoji-button-height: var(--emoji-size); + --emoji-button-width: max-content; + } + #heading { color: var(--cros-text-color-secondary); display: flex; + /* TODO(b/233133645): The sizes need to match the design. */ font-size: 10pt; padding-bottom: var(--emoji-group-heading-padding-bottom); padding-top: var(--emoji-group-heading-padding-top); } + #heading:focus, #heading:active { outline-color: var(--cros-text-color-prominent); @@ -24,14 +91,6 @@ width: 100%; } - #emoji { - display: grid; - gap: var(--emoji-spacing); - grid-auto-rows: max-content; - grid-template-columns: repeat(var(--emoji-per-row), 1fr); - justify-items: center; - } - #show-clear { --cr-icon-button-fill-color: var(--cros-icon-color-primary); height: var(--emoji-group-heading-size); @@ -82,11 +141,6 @@ background-color: var(--cros-button-background-color-secondary-hover); border: 2px solid var(--cros-button-background-color-secondary-hover); } - - :host([v2-enabled]) { - --emoji-size: var(--v2-emoji-size); - --emoji-spacing: var(--v2-emoji-spacing); - } </style> <template is="dom-if" if="[[group]]"> @@ -99,19 +153,20 @@ </template> </div> </template> - <template is = "dom-if" if="[[showClearRecents]]"> +<template is = "dom-if" if="[[showClearRecents]]"> <button id="clear-recents" on-click="onClearRecentsClick"> <div id="clear-recents-hover"> - Clear recently used emojis + Clear recently used [[category]] </div> </button> </template> <div id="emoji"> <div id="fake-focus-target" tabindex="-1"></div> <template is="dom-repeat" items="[[data]]"> + <!-- TODO(b/233130994): Replace emoji-button with button. --> <emoji-button emoji="[[getDisplayEmojiForEmoji(item.base.string)]]" - variants="[[item.alternates]]" tooltip="[[getTooltipForEmoji(item.base)]]" - > + variants="[[item.alternates]]" category="[[category]]" + tooltip="[[getTooltipForEmoji(item.base)]]"> </emoji-button> </template> </div> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js index aacfa0f..b9bc797 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.js
@@ -5,7 +5,6 @@ import './emoji_button.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - import {createCustomEvent, EMOJI_CLEAR_RECENTS_CLICK} from './events.js'; import {CategoryEnum, EmojiVariants} from './types.js'; @@ -23,13 +22,24 @@ /** @type {!Array<EmojiVariants>} */ data: {type: Array, readonly: true}, /** @type {Object<string,string>} */ - preferred: {type: Object}, + preferred: {type: Object, value: {}}, /** @type {boolean} */ clearable: {type: Boolean, value: false}, /** @type {boolean} */ showClearRecents: {type: Boolean, value: false}, /** @type {string} */ - category: {type: String, value: CategoryEnum.EMOJI}, + category: { + type: String, + value: CategoryEnum.EMOJI, + readonly: true, + }, + /** @type {boolean} */ + useFlexLayout: { + type: Boolean, + value: false, + readonly: true, + reflectToAttribute: true, + }, }; } @@ -69,6 +79,22 @@ this.dispatchEvent(createCustomEvent( EMOJI_CLEAR_RECENTS_CLICK, {category: this.category})); } + + /** + * Returns the first emoji button (<button>) in the group. + * + * @returns {Element} The first button if exist, otherwise null. + */ + firstEmojiButton() { + // TODO(b/234074956): Change to optional chaining in typescript. + const emojiButton = this.shadowRoot.querySelector('emoji-button'); + + if (emojiButton) { + return emojiButton.shadowRoot.querySelector('#emoji-button'); + } + + return null; + } } customElements.define(EmojiGroupComponent.is, EmojiGroupComponent);
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html index 4ee120d4..2795136 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html
@@ -359,7 +359,8 @@ <template is="dom-if" if="[[emojiHistory.emoji.length]]"> <emoji-group data="[[emojiHistory.emoji]]" group="[[emojiHistory.group]]" preferred="{}" clearable - class="group history" v2-enabled$="[[v2Enabled]]"> + class="group history" v2-enabled$="[[v2Enabled]]" + category="emoji"> </emoji-group> </template> </div> @@ -367,27 +368,29 @@ <div data-group$="[[getDataGroupIndex('emoji', index)]]"> <emoji-group data="[[item.emoji]]" group="[[item.group]]" preferred="[[preferenceMapping]]" class="group" - v2-enabled$="[[v2Enabled]]"> + v2-enabled$="[[v2Enabled]]" category="emoji"> </emoji-group> </div> </template> <div class="category-gap"></div> + <!-- Start of emoticon groups. --> <template is="dom-if" if="[[v2Enabled]]"> <div data-group="emoticon-history"> <template is="dom-if" if="[[_isHistoryReadyToPresent( emojiGroupsFullyLoaded,emoticonHistory.emoji.length)]]"> - <emoticon-group data="[[emoticonHistory.emoji]]" - group="[[emoticonHistory.group]]" class="group" - data-group="emoticon-history" clearable> - </emoticon-group> + <emoji-group data="[[emoticonHistory.emoji]]" + group="[[emoticonHistory.group]]" + clearable class="group history" + category="emoticon" use-flex-layout> + </emoji-group> </template> </div> <template is="dom-repeat" items="[[emoticonData]]"> <div data-group$="[[getDataGroupIndex('emoticon', index)]]"> - <emoticon-group data="[[item.emoji]]" group="[[item.group]]" - class="group"> - </emoticon-group> + <emoji-group data="[[item.emoji]]" group="[[item.group]]" + class="group" category="emoticon" use-flex-layout> + </emoji-group> </div> </template> </template>
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js index a5e52e0..55d2bf9 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js
@@ -6,7 +6,6 @@ import './emoji_group.js'; import './emoji_group_button.js'; import './emoji_search.js'; -import './emoticon_group.js'; import './text_group_button.js'; import 'chrome://resources/cr_elements/cr_icons_css.m.js'; @@ -692,12 +691,20 @@ } if (this.emoticonHistory.emoji.length > 0) { + /** + * When disabling V2, V1 can still access the history even though there + * is be no emoticon-history element. + * For V2, emoticon can be there but emoji-groups can be loaded later. + */ const emoticonHistoryElement = this.shadowRoot.querySelector( - `div[data-group="emoticon-history"]`).querySelector('emoticon-group'); - if (emoticonHistoryElement != null) { - emoticonHistoryElement.showClearRecents = false; + `div[data-group="emoticon-history"]`); + if (emoticonHistoryElement) { + const emoticonGroup = emoticonHistoryElement.querySelector( + 'emoji-group'); + if (emoticonGroup) { + emoticonGroup.showClearRecents = false; + } } - } } @@ -934,8 +941,8 @@ } /** - * Calculate the data group index for emoji-group and emoticon-group that - * matches with the group id from subcategory metadata. + * Calculate the data group index for different categories + * that matches with the group id from subcategory metadata. * @param {string} category * @param {number} offsetIndex * @returns
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html index 2810023..5f122ea 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html
@@ -123,7 +123,7 @@ #category-button-group { align-items: center; display: flex; - /* + /* * TODO(b/213141035): Change to space-between when symbol category is * re-introduced. */ @@ -179,13 +179,13 @@ </template> </template> <template is="dom-if" if="[[v2Enabled]]"> - <div id="emoji-result"> - <emoji-group data="[[emojiResults]]" preferred="{}"> + <div id="search-results"> + <emoji-group id="emoji-result" data="[[emojiResults]]" + category="emoji"> </emoji-group> - </div> - <div id="emoticon-result"> - <emoticon-group id="emoticon-result" data="[[emoticonResults]]"> - </emoticon-group> + <emoji-group id="emoticon-result" data="[[emoticonResults]]" + category="emoticon" use-flex-layout> + </emoji-group> </div> </template> <template is="dom-if"
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_search.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_search.js index 985878d..73d7486 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_search.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_search.js
@@ -5,7 +5,6 @@ import 'chrome://resources/cr_elements/cr_search_field/cr_search_field.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - import {EmojiButton} from './emoji_button.js'; import {EmojiCategoryButton} from './emoji_category_button.js'; import Fuse from './fuse.js'; @@ -99,6 +98,11 @@ * @param {KeyboardEvent} ev */ onKeyDown(ev) { + // TODO(b/233567886): Implement navigation by keyboard for V2. + if (this.v2Enabled) { + return; + } + const isUp = ev.key === 'ArrowUp'; const isDown = ev.key === 'ArrowDown'; const isEnter = ev.key === 'Enter'; @@ -165,23 +169,23 @@ firstButton.querySelector('emoji-button').click(); } } else { - const emojiButton = this.shadowRoot.querySelector('emoji-group') - .shadowRoot.querySelector('emoji-button'); - const emoticonButton = - this.shadowRoot.querySelector('emoticon-group') - .shadowRoot.querySelector('.emoticon-button'); - if (this.emojiResults.length > 0) { - emojiButton.shadowRoot.querySelector('#emoji-button').focus(); - } else if (this.emoticonResults.length > 0) { - emoticonButton.focus(); + const resultsCount = + this.emojiResults.length + this.emoticonResults.length; + + if (resultsCount === 0) { + return; } - if (isEnter && this.emojiResults.length === 1 && - this.emoticonResults.length === 0) { - emojiButton.shadowRoot.querySelector('#emoji-button').click(); - } else if ( - isEnter && this.emojiResults.length === 0 && - this.emoticonResults.length === 1) { - emoticonButton.click(); + + const firstResultButton = this.findFirstResultButton(); + + if (!firstResultButton) { + throw new Error('Cannot find search result buttons.'); + } + + if (isEnter && resultsCount === 1) { + firstResultButton.click(); + } else { + firstResultButton.focus(); } } } @@ -276,6 +280,23 @@ } /** + * Find the first button in the search result page. + * + * @returns {?HTMLElement} First button or null for no results. + */ + findFirstResultButton() { + const results = this.shadowRoot.querySelector( + '#search-results').querySelectorAll('emoji-group'); + for (const result of results) { + const button = result.firstEmojiButton(); + if (button) { + return button; + } + } + return null; + } + + /** * @param {!Array<!EmojiVariants>} emojiResults * @param {!Array<!EmojiVariants>} emoticonResults * @returns {boolean}
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html b/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html deleted file mode 100644 index f17dc0ba8..0000000 --- a/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.html +++ /dev/null
@@ -1,164 +0,0 @@ -<style> - :host { - margin-top: 10px; - position: relative; - } - - #heading { - color: var(--cros-text-color-secondary); - display: flex; - font-size: 10pt; - height: var(--emoji-group-heading-size); - line-height: var(--emoji-group-heading-size); - padding-bottom: var(--emoji-group-heading-padding-bottom); - padding-top: var(--emoji-group-heading-padding-top); - user-select: none; - width: 100%; - } - - #heading:focus, - #heading:active { - outline-color: var(--cros-text-color-prominent); - outline-width: 2px; - } - - #heading-left { - height: var(--emoji-group-heading-size); - line-height: var(--emoji-group-heading-size); - user-select: none; - width: 100%; - } - - #palette { - display: flex; - flex-wrap: wrap; - gap: 12px 20px; - } - - #fake-focus-target { - position: absolute; - } - - #show-clear { - --cr-icon-button-fill-color: var(--cros-icon-color-primary); - height: var(--emoji-group-heading-size); - left: var(--emoji-picker-last-emoji-left); - margin: 0; - width: var(--emoji-group-heading-size); - } - - #clear-recents { - background-color: var(--cros-bg-color); - border: 2px solid transparent; - border-radius: 4px; - box-shadow: var(--cr-elevation-1); - color: var(--cros-text-color-secondary); - cursor: pointer; - font-family: 'Roboto', sans-serif; - font-size: 12px; - height: var(--emoji-size); - outline: none; - padding: 0; - position: absolute; - right: 0; - top: calc(var(--emoji-group-heading-padding-top) - + var(--emoji-group-heading-padding-bottom) - + var(--emoji-group-heading-size)); - white-space: nowrap; - width: fit-content; - z-index: 200; - } - - #clear-recents:focus, - #clear-recents:active { - border: 2px solid var(--cros-toggle-color); - } - - #clear-recents-hover { - border: 2px solid transparent; - margin: -2px; - /* Padding should be 6/10 not 7/11, but without adding 1 there is - * a weird border.*/ - padding: 7px 11px 7px 11px; - } - - #clear-recents-hover:hover { - background-color: var(--cros-button-background-color-secondary-hover); - border: 2px solid var(--cros-button-background-color-secondary-hover); - } - - .emoticon-button { - background: var(--emoji-background); - border: none; - color: var(--cros-text-color-primary); - cursor: pointer; - font-family: 'Noto Sans CJK JP'; - font-size: 13px; - height: var(--v2-emoji-size); - padding: 6px; - width: max-content; - } - - .emoticon-button:focus, - .emoticon-button:active { - outline-color: var(--cros-focus-ring-color); - outline-style: solid; - outline-width: 2px; - } - - .emoticon-button:hover { - background-color: var(--emoji-hover-background); - } - - .tooltip { - --paper-tooltip-background: var(--cros-tooltip-background-color); - --paper-tooltip-delay-in: var(--emoji-tooltip-delay-in); - --paper-tooltip-delay-out: var(--emoji-tooltip-delay-out); - --paper-tooltip-duration-in: 0; - --paper-tooltip-duration-out: 0; - --paper-tooltip-opacity: 1; - --paper-tooltip-text-color: var(--cros-tooltip-label-color); - } - - .tooltip::part(tooltip) { - box-shadow: var(--cr-elevation-1); - font-family: 'Roboto', sans-serif; - font-size: 12px; - margin: 4px; - padding: 4px 8px 4px 8px; - white-space: nowrap; - } -</style> - -<template is="dom-if" if="[[group]]"> - <div id="heading" role="heading" aria-level="2" tabindex="-1"> - <div id="heading-left">[[group]]</div> - <template is="dom-if" if="[[clearable]]"> - <cr-icon-button id="show-clear" iron-icon="emoji_picker:more_horizontal" - on-click="onClearClick"> - </cr-icon-button> - </template> - </div> -</template> -<template is = "dom-if" if="[[showClearRecents]]"> - <button id="clear-recents" on-click="onClearRecentsClick"> - <div id="clear-recents-hover"> - Clear recently used emoticons - </div> - </button> -</template> -<div id="palette"> - <div id="fake-focus-target" tabindex="-1"></div> - <template is="dom-repeat" items="[[data]]" as="emoticon"> - <button class="emoticon-button" id="[[generateEmoticonId(index)]]" - emoticon-name$="[[emoticon.base.name]]" - on-click="onEmoticonClick" - emoticon-string$="[[emoticon.base.string]]"> - [[emoticon.base.string]] - </button> - <paper-tooltip class="tooltip" for="[[generateEmoticonId(index)]]" - fit-to-visible-bounds part="tooltip" offset="8"> - [[emoticon.base.name]] - </paper-tooltip> - </template> -</div>
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.js b/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.js deleted file mode 100644 index d04d6a1..0000000 --- a/chrome/browser/resources/chromeos/emoji_picker/emoticon_group.js +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js'; - -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {createCustomEvent, EMOJI_BUTTON_CLICK, EMOJI_CLEAR_RECENTS_CLICK} from './events.js'; -import {CategoryEnum, EmojiVariants} from './types.js'; - -class EmoticonGroupComponent extends PolymerElement { - static get is() { - return 'emoticon-group'; - } - - static get template() { - return html`{__html_template__}`; - } - - static get properties() { - return { - /** @type {!Array<EmojiVariants>}*/ - data: {type: Array, readonly: true}, - /** @type {boolean} */ - clearable: {type: Boolean, value: false}, - /** @type {boolean} */ - showClearRecents: {type: Boolean, value: false}, - /** @type {string} */ - category: {type: String, value: CategoryEnum.EMOTICON}, - }; - } - - onEmoticonClick(ev) { - const emoticonString = ev.target.getAttribute('emoticon-string'); - const emoticonName = ev.target.getAttribute('emoticon-name'); - this.dispatchEvent(createCustomEvent(EMOJI_BUTTON_CLICK, { - text: emoticonString, - isVariant: false, - baseEmoji: emoticonString, - allVariants: [], - name: emoticonName, - category: this.category, - })); - } - - /** - * @param {Number} index - * @returns {string} unique string to distinguish different emoticons within - * same group. - */ - generateEmoticonId(index) { - return `emoticon-${index}`; - } - - /** - * Handles the click event for show-clear button which results - * in showing "clear recently used" emoticons button. - * - * @param {Event} ev - */ - onClearClick(ev) { - ev.preventDefault(); - ev.stopPropagation(); - this.showClearRecents = true; - } - - /** - * Handles the event for clicking on the "clear recently used" button. - * It makes "show-clear" button disappear and fires an event - * indicating that the "clear recently used" is clicked. - * - * @fires CustomEvent#`EMOJI_CLEAR_RECENTS_CLICK` - * @param {Event} ev - */ - onClearRecentsClick(ev) { - ev.preventDefault(); - ev.stopPropagation(); - this.showClearRecents = false; - this.dispatchEvent(createCustomEvent( - EMOJI_CLEAR_RECENTS_CLICK, {category: this.category})); - } -} - -customElements.define(EmoticonGroupComponent.is, EmoticonGroupComponent);
diff --git a/chrome/browser/resources/chromeos/login/oobe.css b/chrome/browser/resources/chromeos/login/oobe.css index 4131817..61e6bcbd 100644 --- a/chrome/browser/resources/chromeos/login/oobe.css +++ b/chrome/browser/resources/chromeos/login/oobe.css
@@ -7,15 +7,15 @@ */ :root { - --google-grey-700: rgb(95, 99, 104); --shelf-area-height-base: 57px; --oobe-oobe-dialog-height-base: 504px; --oobe-oobe-dialog-width-base: 461px; + --oobe-bg-color: var(--cros-bg-color); } html, body { - background-color: var(--cros-bg-color); + background-color: var(--oobe-bg-color); height: 100%; transition: background-color 250ms linear; width: 100%; @@ -32,7 +32,6 @@ } body { - background-color: transparent; cursor: default; font-size: 14px; margin: 0; @@ -77,6 +76,7 @@ html[screen=gaia-signin] { /* has to be with px suffix to be used in calc */ --oobe-dialog-side-margin: 0px; + --oobe-bg-color: var(--cros-bg-color-elevation-3); } /* Adapt for horizontal screen */ @@ -99,21 +99,6 @@ outline: none; } -.label, -.flexible-label { - display: block; - margin: 5px 5px 5px 0; - padding: 5px 5px 5px 0; -} - -.label { - width: 170px; -} - -.flexible-label { - max-width: 250px; -} - [hidden] { display: none !important; }
diff --git a/chrome/browser/resources/support_tool/data_collectors.html b/chrome/browser/resources/support_tool/data_collectors.html index 4e5269c..6900ea10 100644 --- a/chrome/browser/resources/support_tool/data_collectors.html +++ b/chrome/browser/resources/support_tool/data_collectors.html
@@ -8,8 +8,7 @@ } </style> -<h2>Collect diagnostics data for support</h2> -<div class="support-tool-title">Select diagnostic data to export</div> +<h2>Step 2 of 4: Select diagnostics data to export</h2> <iron-list class="data-collector-list" items="[[dataCollectors_]]"> <template> <cr-checkbox class="data-collector-checkbox" checked="{{item.isIncluded}}">
diff --git a/chrome/browser/resources/support_tool/data_export_done.html b/chrome/browser/resources/support_tool/data_export_done.html index 78857d2..e32685c 100644 --- a/chrome/browser/resources/support_tool/data_export_done.html +++ b/chrome/browser/resources/support_tool/data_export_done.html
@@ -15,7 +15,7 @@ </style> -<h2>Diagnostics data is exported</h2> +<h2>Step 4 of 4: Diagnostics data is exported</h2> <div class="support-tool-title"> Data has been exported into the selected location </div>
diff --git a/chrome/browser/resources/support_tool/issue_details.html b/chrome/browser/resources/support_tool/issue_details.html index cbf1bc5..920046de 100644 --- a/chrome/browser/resources/support_tool/issue_details.html +++ b/chrome/browser/resources/support_tool/issue_details.html
@@ -30,7 +30,7 @@ } </style> -<h2>Collect diagnostics data for support</h2> +<h2>Step 1 of 4: Describe the issue</h2> <div class="support-tool-title">Support Case ID</div> <cr-input class="support-case-id" value="{{caseId_}}" spellcheck="false" maxlength="20">
diff --git a/chrome/browser/resources/support_tool/pii_selection.html b/chrome/browser/resources/support_tool/pii_selection.html index 9165d5e..1baa18bb 100644 --- a/chrome/browser/resources/support_tool/pii_selection.html +++ b/chrome/browser/resources/support_tool/pii_selection.html
@@ -41,9 +41,11 @@ } </style> -<h2>Review Personally Identifiable Information</h2> +<h2>Step 3 of 4: Review personally identifiable information</h2> <div id="pii-warning-text" class="support-tool-title"> - Diagnostic data collection is complete. Some personally identifiable information was detected. Please select which information you wish to retain. + Diagnostic data collection is complete. Some personally identifiable + information was detected. Select which information you wish to include in + exported data. </div> <div id="detected-pii-container"> <cr-checkbox checked="{{selectAll_}}">
diff --git a/chrome/browser/resources/support_tool/url_generator.html b/chrome/browser/resources/support_tool/url_generator.html index 826689b..be4dad8 100644 --- a/chrome/browser/resources/support_tool/url_generator.html +++ b/chrome/browser/resources/support_tool/url_generator.html
@@ -41,7 +41,7 @@ } </style> -<h2>Generate support tool URL</h2> +<h2>Get a Support Tool link</h2> <div class="support-tool-title">Support Case ID</div> <cr-input id="caseIdInput" class="support-case-id" value="{{caseId_}}" spellcheck="false" maxlength="20" disabled="[[urlGenerated_]]">
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc index 810f67a..2b1f481 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc
@@ -35,15 +35,13 @@ static std::unique_ptr<enterprise_connectors::ContentAnalysisDelegate> Create( base::RepeatingClosure delete_closure, StatusCallback status_callback, - EncryptionStatusCallback encryption_callback, std::string dm_token, content::WebContents* web_contents, Data data, CompletionCallback callback) { auto ret = std::make_unique<UnresponsiveContentAnalysisDelegate>( - delete_closure, status_callback, encryption_callback, - std::move(dm_token), web_contents, std::move(data), - std::move(callback)); + delete_closure, status_callback, std::move(dm_token), web_contents, + std::move(data), std::move(callback)); return ret; } @@ -100,9 +98,6 @@ base::DoNothing(), base::BindRepeating(&DeepScanningBrowserTestBase::StatusCallback, base::Unretained(this)), - base::BindRepeating( - &DeepScanningBrowserTestBase::EncryptionStatusCallback, - base::Unretained(this)), kDmToken)); } @@ -113,9 +108,6 @@ &UnresponsiveContentAnalysisDelegate::Create, base::DoNothing(), base::BindRepeating(&DeepScanningBrowserTestBase::StatusCallback, base::Unretained(this)), - base::BindRepeating( - &DeepScanningBrowserTestBase::EncryptionStatusCallback, - base::Unretained(this)), kDmToken)); } @@ -139,11 +131,6 @@ return connector_status_callback_response_; } -bool DeepScanningBrowserTestBase::EncryptionStatusCallback( - const base::FilePath& path) { - return false; -} - void DeepScanningBrowserTestBase::CreateFilesForTest( const std::vector<std::string>& paths, const std::vector<std::string>& contents,
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h index d43791a..3b39e3e0d 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h
@@ -39,7 +39,6 @@ // Callbacks used to set up the fake delegate factory. enterprise_connectors::ContentAnalysisResponse StatusCallback( const base::FilePath& path); - bool EncryptionStatusCallback(const base::FilePath& path); // Creates temporary files for testing in |temp_dir_|, and add them to |data|. void CreateFilesForTest(
diff --git a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc index 599f51c..f09791d 100644 --- a/chrome/browser/sessions/session_restore_browsertest_chromeos.cc +++ b/chrome/browser/sessions/session_restore_browsertest_chromeos.cc
@@ -12,6 +12,7 @@ #include "base/strings/string_number_conversions.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/ash/crostini/crostini_util.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/defaults.h" @@ -442,7 +443,7 @@ maybe_installation_ = web_app::TestSystemWebAppInstallation::SetUpStandaloneSingleWindowApp(); maybe_installation_->set_update_policy( - web_app::SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); } ~SystemWebAppSessionRestoreTestChromeOS() override = default;
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index cf7cf75..dd3aa720 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -297,10 +297,6 @@ #endif } -bool ChromeSigninClient::IsNonEnterpriseUser(const std::string& username) { - return policy::BrowserPolicyConnector::IsNonEnterpriseUser(username); -} - #if BUILDFLAG(IS_CHROMEOS_LACROS) // Returns the account that must be auto-signed-in to the Main Profile in // Lacros.
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h index 6e1e35f..4f85f2c 100644 --- a/chrome/browser/signin/chrome_signin_client.h +++ b/chrome/browser/signin/chrome_signin_client.h
@@ -64,7 +64,6 @@ std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher( GaiaAuthConsumer* consumer, gaia::GaiaSource source) override; - bool IsNonEnterpriseUser(const std::string& username) override; #if !BUILDFLAG(IS_CHROMEOS_ASH) // network::NetworkConnectionTracker::NetworkConnectionObserver
diff --git a/chrome/browser/speech/chrome_speech_recognition_service.cc b/chrome/browser/speech/chrome_speech_recognition_service.cc index 597a159..98e32ed 100644 --- a/chrome/browser/speech/chrome_speech_recognition_service.cc +++ b/chrome/browser/speech/chrome_speech_recognition_service.cc
@@ -28,12 +28,23 @@ ChromeSpeechRecognitionService::~ChromeSpeechRecognitionService() = default; -void ChromeSpeechRecognitionService::Create( +void ChromeSpeechRecognitionService::BindSpeechRecognitionContext( mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) { LaunchIfNotRunning(); if (speech_recognition_service_.is_bound()) - speech_recognition_service_->BindContext(std::move(receiver)); + speech_recognition_service_->BindSpeechRecognitionContext( + std::move(receiver)); +} + +void ChromeSpeechRecognitionService::BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) { + LaunchIfNotRunning(); + + if (speech_recognition_service_.is_bound()) + speech_recognition_service_->BindAudioSourceSpeechRecognitionContext( + std::move(receiver)); } void ChromeSpeechRecognitionService::LaunchIfNotRunning() {
diff --git a/chrome/browser/speech/chrome_speech_recognition_service.h b/chrome/browser/speech/chrome_speech_recognition_service.h index 27698c17..1524a6d 100644 --- a/chrome/browser/speech/chrome_speech_recognition_service.h +++ b/chrome/browser/speech/chrome_speech_recognition_service.h
@@ -32,8 +32,13 @@ delete; ~ChromeSpeechRecognitionService() override; - void Create(mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - receiver) override; + // SpeechRecognitionService: + void BindSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) + override; + void BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) override; private: // Launches the speech recognition service in a sandboxed utility process.
diff --git a/chrome/browser/speech/cros_speech_recognition_service.cc b/chrome/browser/speech/cros_speech_recognition_service.cc index 7a48af9..b6571df8 100644 --- a/chrome/browser/speech/cros_speech_recognition_service.cc +++ b/chrome/browser/speech/cros_speech_recognition_service.cc
@@ -49,11 +49,17 @@ CrosSpeechRecognitionService::~CrosSpeechRecognitionService() {} -void CrosSpeechRecognitionService::Create( +void CrosSpeechRecognitionService::BindSpeechRecognitionContext( mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) { speech_recognition_contexts_.Add(this, std::move(receiver)); } +void CrosSpeechRecognitionService::BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) { + audio_source_speech_recognition_contexts_.Add(this, std::move(receiver)); +} + void CrosSpeechRecognitionService::BindRecognizer( mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizer> receiver, mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> client,
diff --git a/chrome/browser/speech/cros_speech_recognition_service.h b/chrome/browser/speech/cros_speech_recognition_service.h index fb280ff..531d8bc6 100644 --- a/chrome/browser/speech/cros_speech_recognition_service.h +++ b/chrome/browser/speech/cros_speech_recognition_service.h
@@ -23,6 +23,7 @@ // browser then regular chrome. class CrosSpeechRecognitionService : public ChromeSpeechRecognitionService, + public media::mojom::AudioSourceSpeechRecognitionContext, public media::mojom::SpeechRecognitionContext { public: explicit CrosSpeechRecognitionService(content::BrowserContext* context); @@ -30,8 +31,14 @@ CrosSpeechRecognitionService& operator=(const SpeechRecognitionService&) = delete; ~CrosSpeechRecognitionService() override; - void Create(mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - receiver) override; + + // SpeechRecognitionService: + void BindSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) + override; + void BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) override; // media::mojom::SpeechRecognitionContext void BindRecognizer( @@ -40,6 +47,8 @@ client, media::mojom::SpeechRecognitionOptionsPtr options, BindRecognizerCallback callback) override; + + // media::mojom::AudioSourceSpeechRecognitionContext: void BindAudioSourceFetcher( mojo::PendingReceiver<media::mojom::AudioSourceFetcher> fetcher_receiver, mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> @@ -56,6 +65,8 @@ const base::FilePath& binary_path, const base::FilePath& languagepack_path); + mojo::ReceiverSet<media::mojom::AudioSourceSpeechRecognitionContext> + audio_source_speech_recognition_contexts_; mojo::ReceiverSet<media::mojom::SpeechRecognitionContext> speech_recognition_contexts_; base::WeakPtrFactory<CrosSpeechRecognitionService> weak_factory_{this};
diff --git a/chrome/browser/speech/fake_speech_recognition_service.cc b/chrome/browser/speech/fake_speech_recognition_service.cc index 837837b..78cf41e8 100644 --- a/chrome/browser/speech/fake_speech_recognition_service.cc +++ b/chrome/browser/speech/fake_speech_recognition_service.cc
@@ -17,7 +17,13 @@ FakeSpeechRecognitionService::~FakeSpeechRecognitionService() = default; -void FakeSpeechRecognitionService::Create( +void FakeSpeechRecognitionService::BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) { + audio_source_speech_recognition_contexts_.Add(this, std::move(receiver)); +} + +void FakeSpeechRecognitionService::BindSpeechRecognitionContext( mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) { speech_recognition_contexts_.Add(this, std::move(receiver)); }
diff --git a/chrome/browser/speech/fake_speech_recognition_service.h b/chrome/browser/speech/fake_speech_recognition_service.h index f2a38f4..7d367a6 100644 --- a/chrome/browser/speech/fake_speech_recognition_service.h +++ b/chrome/browser/speech/fake_speech_recognition_service.h
@@ -23,6 +23,7 @@ : public SpeechRecognitionService, public media::mojom::SpeechRecognitionContext, public media::mojom::SpeechRecognitionRecognizer, + public media::mojom::AudioSourceSpeechRecognitionContext, public media::mojom::AudioSourceFetcher { public: FakeSpeechRecognitionService(); @@ -30,8 +31,14 @@ FakeSpeechRecognitionService& operator=(const SpeechRecognitionService&) = delete; ~FakeSpeechRecognitionService() override; - void Create(mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - receiver) override; + + // SpeechRecognitionService: + void BindSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) + override; + void BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) override; // media::mojom::SpeechRecognitionContext: void BindRecognizer( @@ -40,6 +47,8 @@ client, media::mojom::SpeechRecognitionOptionsPtr options, BindRecognizerCallback callback) override; + + // media::mojom::AudioSourceSpeechRecognitionContext: void BindAudioSourceFetcher( mojo::PendingReceiver<media::mojom::AudioSourceFetcher> fetcher_receiver, mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> @@ -104,6 +113,8 @@ mojo::Remote<media::mojom::SpeechRecognitionRecognizerClient> recognizer_client_remote_; + mojo::ReceiverSet<media::mojom::AudioSourceSpeechRecognitionContext> + audio_source_speech_recognition_contexts_; mojo::ReceiverSet<media::mojom::SpeechRecognitionContext> speech_recognition_contexts_; mojo::Receiver<media::mojom::SpeechRecognitionRecognizer>
diff --git a/chrome/browser/speech/on_device_speech_recognizer.cc b/chrome/browser/speech/on_device_speech_recognizer.cc index 13467bc..efb436c0 100644 --- a/chrome/browser/speech/on_device_speech_recognizer.cc +++ b/chrome/browser/speech/on_device_speech_recognizer.cc
@@ -79,11 +79,13 @@ waiting_for_params_(false) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // Connect the SpeechRecognitionContext. - mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - speech_recognition_context_receiver = - speech_recognition_context_.BindNewPipeAndPassReceiver(); - speech_recognition_context_->BindAudioSourceFetcher( + // Connect the AudioSourceSpeechRecognitionContext & bind an + // AudioSourceFetcher recognizer. + CrosSpeechRecognitionServiceFactory::GetForProfile(profile) + ->BindAudioSourceSpeechRecognitionContext( + audio_source_speech_recognition_context_ + .BindNewPipeAndPassReceiver()); + audio_source_speech_recognition_context_->BindAudioSourceFetcher( audio_source_fetcher_.BindNewPipeAndPassReceiver(), speech_recognition_client_receiver_.BindNewPipeAndPassRemote(), media::mojom::SpeechRecognitionOptions::New( @@ -94,19 +96,17 @@ base::BindOnce(&OnDeviceSpeechRecognizer::OnRecognizerBound, weak_factory_.GetWeakPtr()))); - CrosSpeechRecognitionServiceFactory::GetForProfile(profile)->Create( - std::move(speech_recognition_context_receiver)); - - speech_recognition_context_.set_disconnect_handler(media::BindToCurrentLoop( - base::BindOnce(&OnDeviceSpeechRecognizer::OnRecognizerDisconnected, - weak_factory_.GetWeakPtr()))); + audio_source_speech_recognition_context_.set_disconnect_handler( + media::BindToCurrentLoop( + base::BindOnce(&OnDeviceSpeechRecognizer::OnRecognizerDisconnected, + weak_factory_.GetWeakPtr()))); } OnDeviceSpeechRecognizer::~OnDeviceSpeechRecognizer() { audio_source_fetcher_->Stop(); audio_source_fetcher_.reset(); speech_recognition_client_receiver_.reset(); - speech_recognition_context_.reset(); + audio_source_speech_recognition_context_.reset(); } void OnDeviceSpeechRecognizer::Start() {
diff --git a/chrome/browser/speech/on_device_speech_recognizer.h b/chrome/browser/speech/on_device_speech_recognizer.h index 24b56a24..02f5cba 100644 --- a/chrome/browser/speech/on_device_speech_recognizer.h +++ b/chrome/browser/speech/on_device_speech_recognizer.h
@@ -87,8 +87,8 @@ // to override default behavior. std::unique_ptr<media::AudioSystem> audio_system_; - mojo::Remote<media::mojom::SpeechRecognitionContext> - speech_recognition_context_; + mojo::Remote<media::mojom::AudioSourceSpeechRecognitionContext> + audio_source_speech_recognition_context_; mojo::Remote<media::mojom::AudioSourceFetcher> audio_source_fetcher_; mojo::Receiver<media::mojom::SpeechRecognitionRecognizerClient> speech_recognition_client_receiver_{this};
diff --git a/chrome/browser/speech/speech_recognition_service.h b/chrome/browser/speech/speech_recognition_service.h index dfea36f..5a801a5 100644 --- a/chrome/browser/speech/speech_recognition_service.h +++ b/chrome/browser/speech/speech_recognition_service.h
@@ -13,9 +13,12 @@ class SpeechRecognitionService : public KeyedService { public: - virtual void Create( + virtual void BindSpeechRecognitionContext( mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> receiver) = 0; + virtual void BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + receiver) = 0; }; } // namespace speech
diff --git a/chrome/browser/speech/speech_recognition_service_browsertest.cc b/chrome/browser/speech/speech_recognition_service_browsertest.cc index 2641fa1c..0801c91a 100644 --- a/chrome/browser/speech/speech_recognition_service_browsertest.cc +++ b/chrome/browser/speech/speech_recognition_service_browsertest.cc
@@ -176,6 +176,8 @@ base::FilePath test_data_dir_; base::test::ScopedFeatureList scoped_feature_list_; + mojo::Remote<media::mojom::AudioSourceSpeechRecognitionContext> + audio_source_speech_recognition_context_; mojo::Remote<media::mojom::SpeechRecognitionContext> speech_recognition_context_; @@ -255,20 +257,14 @@ static_cast<content::BrowserContext*>(browser()->profile()); auto* service = new ChromeSpeechRecognitionService(browser_context); - mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - speech_recognition_context_receiver = - speech_recognition_context_.BindNewPipeAndPassReceiver(); - service->Create(std::move(speech_recognition_context_receiver)); - - mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizer> - pending_recognizer_receiver = - speech_recognition_recognizer_.BindNewPipeAndPassReceiver(); + service->BindSpeechRecognitionContext( + speech_recognition_context_.BindNewPipeAndPassReceiver()); bool is_multichannel_supported = true; auto run_loop = std::make_unique<base::RunLoop>(); // Bind the recognizer pipes used to send audio and receive results. speech_recognition_context_->BindRecognizer( - std::move(pending_recognizer_receiver), + speech_recognition_recognizer_.BindNewPipeAndPassReceiver(), speech_recognition_client_receiver_.BindNewPipeAndPassRemote(), media::mojom::SpeechRecognitionOptions::New( media::mojom::SpeechRecognitionMode::kCaption, @@ -291,15 +287,13 @@ static_cast<content::BrowserContext*>(browser()->profile()); auto* service = new ChromeSpeechRecognitionService(browser_context); - mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - speech_recognition_context_receiver = - speech_recognition_context_.BindNewPipeAndPassReceiver(); - service->Create(std::move(speech_recognition_context_receiver)); + service->BindAudioSourceSpeechRecognitionContext( + audio_source_speech_recognition_context_.BindNewPipeAndPassReceiver()); bool is_multichannel_supported = true; auto run_loop = std::make_unique<base::RunLoop>(); // Bind the recognizer pipes used to send audio and receive results. - speech_recognition_context_->BindAudioSourceFetcher( + audio_source_speech_recognition_context_->BindAudioSourceFetcher( audio_source_fetcher_.BindNewPipeAndPassReceiver(), speech_recognition_client_receiver_.BindNewPipeAndPassRemote(), media::mojom::SpeechRecognitionOptions::New(
diff --git a/chrome/browser/supervised_user/supervised_user_metrics_service.cc b/chrome/browser/supervised_user/supervised_user_metrics_service.cc index 4eb74cda..722d106 100644 --- a/chrome/browser/supervised_user/supervised_user_metrics_service.cc +++ b/chrome/browser/supervised_user/supervised_user_metrics_service.cc
@@ -56,7 +56,7 @@ CheckForNewDay(); // Check for a new day every |kTimerInterval| as well. - DLOG(WARNING) << "If your test is uses mock timers and hangs, you may need " + DLOG(WARNING) << "If your test uses mock timers and hangs, you may need " "to call Shutdown() on SupervisedUserMetricsService."; timer_.Start(FROM_HERE, kTimerInterval, this, &SupervisedUserMetricsService::CheckForNewDay);
diff --git a/chrome/browser/sync/test/integration/ash_custom_passphrase_sharing_sync_test.cc b/chrome/browser/sync/test/integration/ash_custom_passphrase_sharing_sync_test.cc index 4cf24b2..f653690 100644 --- a/chrome/browser/sync/test/integration/ash_custom_passphrase_sharing_sync_test.cc +++ b/chrome/browser/sync/test/integration/ash_custom_passphrase_sharing_sync_test.cc
@@ -326,9 +326,9 @@ // Mimic that user set custom passphrase using current client. const std::string kPassphrase = "hunter2"; GetSyncService(0)->GetUserSettings()->SetEncryptionPassphrase(kPassphrase); - ASSERT_TRUE(ServerNigoriChecker(GetSyncService(0), GetFakeServer(), - syncer::PassphraseType::kCustomPassphrase) - .Wait()); + ASSERT_TRUE( + ServerPassphraseTypeChecker(syncer::PassphraseType::kCustomPassphrase) + .Wait()); // Lacros should be eventually notified that passphrase is available and be // able to retrieve it.
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc index 6d04637..f736e24 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.cc +++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/test/integration/fake_server_match_status_checker.h" #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/undo/bookmark_undo_service_factory.h" @@ -1148,13 +1149,9 @@ } ServerBookmarksEqualityChecker::ServerBookmarksEqualityChecker( - syncer::SyncServiceImpl* service, - fake_server::FakeServer* fake_server, std::vector<ExpectedBookmark> expected_bookmarks, syncer::Cryptographer* cryptographer) - : SingleClientStatusChangeChecker(service), - fake_server_(fake_server), - cryptographer_(cryptographer), + : cryptographer_(cryptographer), expected_bookmarks_(std::move(expected_bookmarks)) {} bool ServerBookmarksEqualityChecker::IsExitConditionSatisfied( @@ -1162,7 +1159,7 @@ *os << "Waiting for server-side bookmarks to match expected."; std::vector<sync_pb::SyncEntity> entities = - fake_server_->GetSyncEntitiesByModelType(syncer::BOOKMARKS); + fake_server()->GetSyncEntitiesByModelType(syncer::BOOKMARKS); if (expected_bookmarks_.size() != entities.size()) { return false; }
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.h b/chrome/browser/sync/test/integration/bookmarks_helper.h index f9da05a..3930e50 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.h +++ b/chrome/browser/sync/test/integration/bookmarks_helper.h
@@ -18,6 +18,7 @@ #include "base/sequence_checker.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/sync/test/integration/await_match_status_change_checker.h" +#include "chrome/browser/sync/test/integration/fake_server_match_status_checker.h" #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "components/bookmarks/browser/bookmark_model_observer.h" @@ -478,7 +479,8 @@ // Checker used to block until the bookmarks on the server match a given set of // expected bookmarks. The |title| is comapred to both legacy and full titles. -class ServerBookmarksEqualityChecker : public SingleClientStatusChangeChecker { +class ServerBookmarksEqualityChecker + : public fake_server::FakeServerMatchStatusChecker { public: struct ExpectedBookmark { // Used to check both legacy and full titles in specifics. @@ -491,8 +493,6 @@ // will be used to decrypt the data prior to checking for equality. // |fake_server| must not be nullptr and must outlive this object. ServerBookmarksEqualityChecker( - syncer::SyncServiceImpl* service, - fake_server::FakeServer* fake_server, std::vector<ExpectedBookmark> expected_bookmarks, syncer::Cryptographer* cryptographer); @@ -506,7 +506,6 @@ ~ServerBookmarksEqualityChecker() override; private: - raw_ptr<fake_server::FakeServer> fake_server_; raw_ptr<syncer::Cryptographer> cryptographer_; const std::vector<ExpectedBookmark> expected_bookmarks_; };
diff --git a/chrome/browser/sync/test/integration/device_info_helper.cc b/chrome/browser/sync/test/integration/device_info_helper.cc index aed2351..8691ce5 100644 --- a/chrome/browser/sync/test/integration/device_info_helper.cc +++ b/chrome/browser/sync/test/integration/device_info_helper.cc
@@ -4,17 +4,13 @@ #include "chrome/browser/sync/test/integration/device_info_helper.h" #include "components/sync/protocol/sync_entity.pb.h" +#include "components/sync/test/fake_server/fake_server.h" ServerDeviceInfoMatchChecker::ServerDeviceInfoMatchChecker( - fake_server::FakeServer* fake_server, const Matcher& matcher) - : fake_server_(fake_server), matcher_(matcher) { - fake_server->AddObserver(this); -} + : matcher_(matcher) {} -ServerDeviceInfoMatchChecker::~ServerDeviceInfoMatchChecker() { - fake_server_->RemoveObserver(this); -} +ServerDeviceInfoMatchChecker::~ServerDeviceInfoMatchChecker() = default; void ServerDeviceInfoMatchChecker::OnCommit( const std::string& committer_invalidator_client_id, @@ -26,7 +22,7 @@ bool ServerDeviceInfoMatchChecker::IsExitConditionSatisfied(std::ostream* os) { std::vector<sync_pb::SyncEntity> entities = - fake_server_->GetSyncEntitiesByModelType(syncer::DEVICE_INFO); + fake_server()->GetSyncEntitiesByModelType(syncer::DEVICE_INFO); testing::StringMatchResultListener result_listener; const bool matches =
diff --git a/chrome/browser/sync/test/integration/device_info_helper.h b/chrome/browser/sync/test/integration/device_info_helper.h index da48133..29aa0b7 100644 --- a/chrome/browser/sync/test/integration/device_info_helper.h +++ b/chrome/browser/sync/test/integration/device_info_helper.h
@@ -9,8 +9,7 @@ #include <string> #include "base/memory/raw_ptr.h" -#include "chrome/browser/sync/test/integration/status_change_checker.h" -#include "components/sync/test/fake_server/fake_server.h" +#include "chrome/browser/sync/test/integration/fake_server_match_status_checker.h" #include "testing/gtest/include/gtest/gtest.h" namespace sync_pb { @@ -19,13 +18,12 @@ // A helper class that waits for a certain set of DeviceInfos on the FakeServer. // The desired state is passed in as a GTest matcher. -class ServerDeviceInfoMatchChecker : public StatusChangeChecker, - fake_server::FakeServer::Observer { +class ServerDeviceInfoMatchChecker + : public fake_server::FakeServerMatchStatusChecker { public: using Matcher = testing::Matcher<std::vector<sync_pb::SyncEntity>>; - ServerDeviceInfoMatchChecker(fake_server::FakeServer* fake_server, - const Matcher& matcher); + explicit ServerDeviceInfoMatchChecker(const Matcher& matcher); ~ServerDeviceInfoMatchChecker() override; ServerDeviceInfoMatchChecker(const ServerDeviceInfoMatchChecker&) = delete; ServerDeviceInfoMatchChecker& operator=(const ServerDeviceInfoMatchChecker&) = @@ -39,7 +37,6 @@ bool IsExitConditionSatisfied(std::ostream* os) override; private: - const raw_ptr<fake_server::FakeServer> fake_server_; const Matcher matcher_; };
diff --git a/chrome/browser/sync/test/integration/encryption_helper.cc b/chrome/browser/sync/test/integration/encryption_helper.cc index cb19b0a..ed68f37b 100644 --- a/chrome/browser/sync/test/integration/encryption_helper.cc +++ b/chrome/browser/sync/test/integration/encryption_helper.cc
@@ -13,20 +13,16 @@ #include "components/sync/driver/sync_service_impl.h" #include "testing/gtest/include/gtest/gtest.h" -ServerNigoriChecker::ServerNigoriChecker( - syncer::SyncServiceImpl* service, - fake_server::FakeServer* fake_server, +ServerPassphraseTypeChecker::ServerPassphraseTypeChecker( syncer::PassphraseType expected_passphrase_type) - : SingleClientStatusChangeChecker(service), - fake_server_(fake_server), - expected_passphrase_type_(expected_passphrase_type) {} + : expected_passphrase_type_(expected_passphrase_type) {} -bool ServerNigoriChecker::IsExitConditionSatisfied(std::ostream* os) { +bool ServerPassphraseTypeChecker::IsExitConditionSatisfied(std::ostream* os) { *os << "Waiting for a Nigori node with the proper passphrase type to become " "available on the server."; std::vector<sync_pb::SyncEntity> nigori_entities = - fake_server_->GetPermanentSyncEntitiesByModelType(syncer::NIGORI); + fake_server()->GetPermanentSyncEntitiesByModelType(syncer::NIGORI); EXPECT_LE(nigori_entities.size(), 1U); return !nigori_entities.empty() && syncer::ProtoPassphraseInt32ToEnum( @@ -35,16 +31,12 @@ } ServerNigoriKeyNameChecker::ServerNigoriKeyNameChecker( - const std::string& expected_key_name, - syncer::SyncServiceImpl* service, - fake_server::FakeServer* fake_server) - : SingleClientStatusChangeChecker(service), - fake_server_(fake_server), - expected_key_name_(expected_key_name) {} + const std::string& expected_key_name) + : expected_key_name_(expected_key_name) {} bool ServerNigoriKeyNameChecker::IsExitConditionSatisfied(std::ostream* os) { std::vector<sync_pb::SyncEntity> nigori_entities = - fake_server_->GetPermanentSyncEntitiesByModelType(syncer::NIGORI); + fake_server()->GetPermanentSyncEntitiesByModelType(syncer::NIGORI); DCHECK_EQ(nigori_entities.size(), 1U); const std::string given_key_name =
diff --git a/chrome/browser/sync/test/integration/encryption_helper.h b/chrome/browser/sync/test/integration/encryption_helper.h index 0b596274..44c4675c 100644 --- a/chrome/browser/sync/test/integration/encryption_helper.h +++ b/chrome/browser/sync/test/integration/encryption_helper.h
@@ -10,6 +10,7 @@ #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/sync/test/integration/fake_server_match_status_checker.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "chrome/browser/sync/test/integration/status_change_checker.h" #include "components/sync/base/passphrase_enums.h" @@ -18,31 +19,28 @@ // Checker used to block until a Nigori with a given passphrase type is // available on the server. -class ServerNigoriChecker : public SingleClientStatusChangeChecker { +class ServerPassphraseTypeChecker + : public fake_server::FakeServerMatchStatusChecker { public: - ServerNigoriChecker(syncer::SyncServiceImpl* service, - fake_server::FakeServer* fake_server, - syncer::PassphraseType expected_passphrase_type); + explicit ServerPassphraseTypeChecker( + syncer::PassphraseType expected_passphrase_type); bool IsExitConditionSatisfied(std::ostream* os) override; private: - const raw_ptr<fake_server::FakeServer> fake_server_; const syncer::PassphraseType expected_passphrase_type_; }; // Checker used to block until a Nigori with a given keybag encryption key name // is available on the server. -class ServerNigoriKeyNameChecker : public SingleClientStatusChangeChecker { +class ServerNigoriKeyNameChecker + : public fake_server::FakeServerMatchStatusChecker { public: - ServerNigoriKeyNameChecker(const std::string& expected_key_name, - syncer::SyncServiceImpl* service, - fake_server::FakeServer* fake_server); + explicit ServerNigoriKeyNameChecker(const std::string& expected_key_name); bool IsExitConditionSatisfied(std::ostream* os) override; private: - const raw_ptr<fake_server::FakeServer> fake_server_; const std::string expected_key_name_; };
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc index 4cfbb85..7ea4ae80 100644 --- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -1503,7 +1503,6 @@ ASSERT_TRUE( UpdatedProgressMarkerChecker(GetSyncService(kSingleProfileIndex)).Wait()); ASSERT_TRUE(bookmarks_helper::ServerBookmarksEqualityChecker( - GetSyncService(kSingleProfileIndex), GetFakeServer(), {{title, GURL(kBookmarkPageUrl)}}, /*cryptographer=*/nullptr) .Wait()); @@ -1546,7 +1545,6 @@ ASSERT_TRUE(GetClient(kSingleProfileIndex)->StartSyncService()); ASSERT_TRUE(GetClient(kSingleProfileIndex)->AwaitEngineInitialization()); ASSERT_TRUE(bookmarks_helper::ServerBookmarksEqualityChecker( - GetSyncService(kSingleProfileIndex), GetFakeServer(), {{new_title, url}}, /*cryptographer=*/nullptr) .Wait()); @@ -1612,7 +1610,6 @@ ASSERT_TRUE(SetupSync()); ASSERT_TRUE(bookmarks_helper::ServerBookmarksEqualityChecker( - GetSyncService(kSingleProfileIndex), GetFakeServer(), {{title, /*url=*/GURL()}}, /*cryptographer=*/nullptr) .Wait()); @@ -1798,7 +1795,6 @@ // Wait until the local bookmark gets committed. ASSERT_TRUE(bookmarks_helper::ServerBookmarksEqualityChecker( - GetSyncService(kSingleProfileIndex), GetFakeServer(), {{kTitle, /*url=*/GURL()}}, /*cryptographer=*/nullptr) .Wait());
diff --git a/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc b/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc index 71d179f..b93912d212 100644 --- a/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc
@@ -106,8 +106,7 @@ const std::string& passphrase) { std::unique_ptr<Cryptographer> cryptographer = CreateCryptographerFromServerNigori(passphrase); - return ServerBookmarksEqualityChecker(GetSyncService(), GetFakeServer(), - expected_bookmarks, + return ServerBookmarksEqualityChecker(expected_bookmarks, cryptographer.get()) .Wait(); } @@ -115,16 +114,13 @@ bool WaitForUnencryptedServerBookmarks( const std::vector<ServerBookmarksEqualityChecker::ExpectedBookmark>& expected_bookmarks) { - return ServerBookmarksEqualityChecker(GetSyncService(), GetFakeServer(), - expected_bookmarks, + return ServerBookmarksEqualityChecker(expected_bookmarks, /*cryptographer=*/nullptr) .Wait(); } bool WaitForNigori(PassphraseType expected_passphrase_type) { - return ServerNigoriChecker(GetSyncService(), GetFakeServer(), - expected_passphrase_type) - .Wait(); + return ServerPassphraseTypeChecker(expected_passphrase_type).Wait(); } bool WaitForPassphraseRequiredState(bool desired_state) {
diff --git a/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc b/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc index aa81f82..501a9c7 100644 --- a/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc
@@ -204,10 +204,9 @@ ASSERT_TRUE(SetupSync()); // The local device should eventually be committed to the server. - EXPECT_TRUE( - ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) - .Wait()); + EXPECT_TRUE(ServerDeviceInfoMatchChecker( + ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) + .Wait()); } IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest, DownloadRemoteDevices) { @@ -286,10 +285,9 @@ ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::DEVICE_INFO)); // The local device should eventually be committed to the server. - EXPECT_TRUE( - ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) - .Wait()); + EXPECT_TRUE(ServerDeviceInfoMatchChecker( + ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) + .Wait()); } IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest, @@ -323,10 +321,9 @@ IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest, ShouldSetTheOnlyClientFlag) { ASSERT_TRUE(SetupSync()); - ASSERT_TRUE( - ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) - .Wait()); + ASSERT_TRUE(ServerDeviceInfoMatchChecker( + ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) + .Wait()); sync_pb::ClientToServerMessage message; GetFakeServer()->GetLastCommitMessage(&message); @@ -364,7 +361,6 @@ ASSERT_TRUE(SetupSync()); ASSERT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), UnorderedElementsAre(HasCacheGuid(GetLocalCacheGuid()), HasCacheGuid(CacheGuidForSuffix(1)))) .Wait()); @@ -397,7 +393,6 @@ GetClient(0)->StartSyncService(); ASSERT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), UnorderedElementsAre(HasCacheGuid(GetLocalCacheGuid()), HasCacheGuid(CacheGuidForSuffix(1)))) .Wait()); @@ -421,10 +416,9 @@ server_device_infos.front())); // On receiving the tombstone, the client should reupload its own device info. - EXPECT_TRUE( - ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) - .Wait()); + EXPECT_TRUE(ServerDeviceInfoMatchChecker( + ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) + .Wait()); } // PRE_* tests aren't supported on Android browser tests. @@ -432,10 +426,9 @@ IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest, PRE_ShouldNotSendDeviceInfoAfterBrowserRestart) { ASSERT_TRUE(SetupSync()); - EXPECT_TRUE( - ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) - .Wait()); + EXPECT_TRUE(ServerDeviceInfoMatchChecker( + ElementsAre(HasCacheGuid(GetLocalCacheGuid()))) + .Wait()); } IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest,
diff --git a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc index 616b83ba..669c227 100644 --- a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
@@ -429,7 +429,7 @@ // The client should decrypt the update and re-commit an unencrypted version. EXPECT_TRUE(bookmarks_helper::BookmarksTitleChecker(0, kTitle, 1).Wait()); EXPECT_TRUE(bookmarks_helper::ServerBookmarksEqualityChecker( - GetSyncService(0), GetFakeServer(), {{kTitle, kUrl}}, + {{kTitle, kUrl}}, /*cryptographer=*/nullptr) .Wait()); } @@ -473,9 +473,7 @@ KeystoreKeyParamsForTesting(keystore_keys[1]); const std::string expected_key_bag_key_name = ComputeKeyName(new_keystore_key_params); - EXPECT_TRUE(ServerNigoriKeyNameChecker(expected_key_bag_key_name, - GetSyncService(0), GetFakeServer()) - .Wait()); + EXPECT_TRUE(ServerNigoriKeyNameChecker(expected_key_bag_key_name).Wait()); } // Performs initial sync with backward compatible keystore Nigori. @@ -508,9 +506,7 @@ const std::string expected_key_bag_key_name = ComputeKeyName(KeystoreKeyParamsForTesting( /*raw_key=*/GetFakeServer()->GetKeystoreKeys().back())); - EXPECT_TRUE(ServerNigoriKeyNameChecker(expected_key_bag_key_name, - GetSyncService(0), GetFakeServer()) - .Wait()); + EXPECT_TRUE(ServerNigoriKeyNameChecker(expected_key_bag_key_name).Wait()); } // Tests that client can decrypt |pending_keys| with implicit passphrase in @@ -576,9 +572,9 @@ Eq(sync_pb::NigoriSpecifics::IMPLICIT_PASSPHRASE)); ASSERT_TRUE(SetupClients()); - EXPECT_TRUE(ServerNigoriChecker(GetSyncService(0), GetFakeServer(), - syncer::PassphraseType::kKeystorePassphrase) - .Wait()); + EXPECT_TRUE( + ServerPassphraseTypeChecker(syncer::PassphraseType::kKeystorePassphrase) + .Wait()); } class SingleClientNigoriWithWebApiTest : public SyncTest {
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc index 60f277c..d91667e 100644 --- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -175,9 +175,9 @@ IN_PROC_BROWSER_TEST_F(SingleClientPasswordsSyncTestWithVerifier, ReencryptsDataWhenPassphraseIsSet) { ASSERT_TRUE(SetupSync()); - ASSERT_TRUE(ServerNigoriChecker(GetSyncService(0), fake_server_.get(), - syncer::PassphraseType::kKeystorePassphrase) - .Wait()); + ASSERT_TRUE( + ServerPassphraseTypeChecker(syncer::PassphraseType::kKeystorePassphrase) + .Wait()); PasswordForm form = CreateTestPasswordForm(0); GetVerifierProfilePasswordStoreInterface()->AddLogin(form); @@ -203,9 +203,9 @@ ASSERT_FALSE(prior_encryption_key_name.empty()); GetSyncService(0)->GetUserSettings()->SetEncryptionPassphrase("hunter2"); - ASSERT_TRUE(ServerNigoriChecker(GetSyncService(0), fake_server_.get(), - syncer::PassphraseType::kCustomPassphrase) - .Wait()); + ASSERT_TRUE( + ServerPassphraseTypeChecker(syncer::PassphraseType::kCustomPassphrase) + .Wait()); ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); const std::vector<sync_pb::SyncEntity> entities =
diff --git a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc index b5c2be0c..5164490 100644 --- a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc
@@ -225,7 +225,6 @@ // also enabled. EXPECT_TRUE( ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(AllOf(InterestedDataTypesAre(interested_data_types), Not(HasInstanceIdToken())))) .Wait()); @@ -300,7 +299,6 @@ // The local device should eventually be committed to the server. EXPECT_TRUE( ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(AllOf(InterestedDataTypesAre(interested_data_types), HasInstanceIdToken(fcm_token)))) .Wait()); @@ -359,8 +357,7 @@ // Commit a new bookmark to check if the next commit message has FCM // registration tokens. AddFolder(0, GetBookmarkBarNode(0), 0, kTitle); - ASSERT_TRUE(ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), - {{kTitle, GURL()}}, + ASSERT_TRUE(ServerBookmarksEqualityChecker({{kTitle, GURL()}}, /*cryptographer=*/nullptr) .Wait()); @@ -440,7 +437,6 @@ // Wait until DeviceInfo is updated. ASSERT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasBeenUpdatedAfter(last_updated_timestamp))) .Wait()); @@ -448,16 +444,14 @@ // more GetUpdates request if it was triggered. const std::string kTitle1 = "Title 1"; AddFolder(0, GetBookmarkBarNode(0), 0, kTitle1); - ASSERT_TRUE(ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), - {{kTitle1, GURL()}}, + ASSERT_TRUE(ServerBookmarksEqualityChecker({{kTitle1, GURL()}}, /*cryptographer=*/nullptr) .Wait()); const std::string kTitle2 = "Title 2"; AddFolder(0, GetBookmarkBarNode(0), 0, kTitle2); ASSERT_TRUE( - ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), - {{kTitle1, GURL()}, {kTitle2, GURL()}}, + ServerBookmarksEqualityChecker({{kTitle1, GURL()}, {kTitle2, GURL()}}, /*cryptographer=*/nullptr) .Wait()); @@ -527,7 +521,6 @@ // The local device should eventually be committed to the server. EXPECT_TRUE( ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(AllOf(InterestedDataTypesAre(interested_data_types), HasInstanceIdToken(fcm_token)))) .Wait()); @@ -574,7 +567,6 @@ // The local device should eventually be committed to the server. BOOKMARKS // should be included in interested types, since it's enabled by default. EXPECT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(InterestedDataTypesContain(syncer::BOOKMARKS))) .Wait()); @@ -585,7 +577,6 @@ // should not be included in interested types, as it was disabled. EXPECT_TRUE( ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(Not(InterestedDataTypesContain(syncer::BOOKMARKS)))) .Wait()); @@ -597,7 +588,6 @@ // The local device should eventually be committed to the server. BOOKMARKS // should now be included in interested types. EXPECT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(InterestedDataTypesContain(syncer::BOOKMARKS))) .Wait()); // The bookmark should get synced now. @@ -628,9 +618,9 @@ const std::string old_token = *SyncInvalidationsServiceFactory::GetForProfile(GetProfile(0)) ->GetFCMRegistrationToken(); - EXPECT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(HasInstanceIdToken(old_token))) - .Wait()); + EXPECT_TRUE( + ServerDeviceInfoMatchChecker(ElementsAre(HasInstanceIdToken(old_token))) + .Wait()); // Sign out. The FCM token should be cleared. GetClient(0)->SignOutPrimaryAccount(); @@ -651,11 +641,10 @@ EXPECT_FALSE(new_token.empty()); // New device info should eventually be committed to the server (but the old // device info will remain on the server). The FCM token should be present. - EXPECT_TRUE( - ServerDeviceInfoMatchChecker( - GetFakeServer(), UnorderedElementsAre(HasInstanceIdToken(old_token), - HasInstanceIdToken(new_token))) - .Wait()); + EXPECT_TRUE(ServerDeviceInfoMatchChecker( + UnorderedElementsAre(HasInstanceIdToken(old_token), + HasInstanceIdToken(new_token))) + .Wait()); } #endif // !BUILDFLAG(IS_CHROMEOS_ASH) @@ -684,7 +673,6 @@ PRE_ShouldResendDeviceInfoWithInterestedDataTypes) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), UnorderedElementsAre(HasCacheGuid(GetLocalCacheGuid()))) .Wait()); } @@ -697,7 +685,6 @@ ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); EXPECT_TRUE(ServerDeviceInfoMatchChecker( - GetFakeServer(), ElementsAre(InterestedDataTypesContain(syncer::NIGORI))) .Wait()); }
diff --git a/chrome/browser/sync/test/integration/sync_errors_test.cc b/chrome/browser/sync/test/integration/sync_errors_test.cc index 0d16d61..19afb5e 100644 --- a/chrome/browser/sync/test/integration/sync_errors_test.cc +++ b/chrome/browser/sync/test/integration/sync_errors_test.cc
@@ -388,7 +388,6 @@ // The bookmark should get committed successfully. EXPECT_TRUE(bookmarks_helper::ServerBookmarksEqualityChecker( - GetSyncService(0), GetFakeServer(), {{kBookmarkFolderTitle, GURL()}}, /*cryptographer=*/nullptr) .Wait());
diff --git a/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc b/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc index 7349c99..0ecfea6 100644 --- a/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc +++ b/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc
@@ -47,8 +47,7 @@ ASSERT_TRUE(AddFolder(0, 0, kFolderTitle1)); std::vector<ServerBookmarksEqualityChecker::ExpectedBookmark> expected_bookmarks = {{kFolderTitle1, GURL()}}; - ASSERT_TRUE(ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), - expected_bookmarks, + ASSERT_TRUE(ServerBookmarksEqualityChecker(expected_bookmarks, /*cryptographer=*/nullptr) .Wait()); @@ -77,8 +76,7 @@ // Verify that sync was able to recover. expected_bookmarks.push_back({kFolderTitle2, GURL()}); - EXPECT_TRUE(ServerBookmarksEqualityChecker(GetSyncService(0), GetFakeServer(), - expected_bookmarks, + EXPECT_TRUE(ServerBookmarksEqualityChecker(expected_bookmarks, /*cryptographer=*/nullptr) .Wait());
diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc b/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc index 18064a2..51802b0 100644 --- a/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc
@@ -492,7 +492,9 @@ GetAppSorting(GetProfile(1))->GetAppLaunchOrdinal(app_id)); } -IN_PROC_BROWSER_TEST_F(TwoClientWebAppsBMOSyncTest, AppSortingFixCollisions) { +// Test is flaky (crbug.com/1313368). +IN_PROC_BROWSER_TEST_F(TwoClientWebAppsBMOSyncTest, + DISABLED_AppSortingFixCollisions) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameWebAppIds()); ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/sync/test/integration/typed_urls_helper.cc b/chrome/browser/sync/test/integration/typed_urls_helper.cc index 0f0555d8..1cb8e0d 100644 --- a/chrome/browser/sync/test/integration/typed_urls_helper.cc +++ b/chrome/browser/sync/test/integration/typed_urls_helper.cc
@@ -176,7 +176,7 @@ bool RunOnDBThread(history::HistoryBackend* backend, history::HistoryDatabase* db) override { // Fetch the typed URLs. - db->GetAllSyncMetadata(metadata_batch_); + db->GetTypedURLMetadataDB()->GetAllSyncMetadata(metadata_batch_); wait_event_->Signal(); return true; } @@ -199,7 +199,8 @@ bool RunOnDBThread(history::HistoryBackend* backend, history::HistoryDatabase* db) override { // Write the metadata to the DB. - db->UpdateSyncMetadata(syncer::TYPED_URLS, storage_key_, metadata_); + db->GetTypedURLMetadataDB()->UpdateSyncMetadata(syncer::TYPED_URLS, + storage_key_, metadata_); wait_event_->Signal(); return true; }
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 5c4445e8c..725c2ae 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -1070,7 +1070,7 @@ Help us build a better web </message> <message name="IDS_PRIVACY_SANDBOX_NOTICE_SHEET_DESCRIPTION" desc="" translateable="false"> - During trials, Chrome is exploring ways to limit spam, fraud, and sharing between sites. Chrome also estimates your interests that sites can use to show you ads. You can manage your interests in settings. + During trials, Chrome is exploring ways to limit spam, fraud, and sharing between sites. Chrome also <ph name="BEGIN_LINK"><link></ph>estimates your interests<ph name="END_LINK"></link></ph> that sites can use to show you ads. You can manage your interests in settings. </message> <!-- Secure DNS Settings. Used by //chrome/browser/privacy. -->
diff --git a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc index fe9fe6c..f52d964 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/ash/login/ui/user_adding_screen.h" #include "chrome/browser/ash/login/users/chrome_user_manager.h" #include "chrome/browser/ash/login/wizard_controller.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/profiles/profile.h" @@ -53,7 +54,6 @@ #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" @@ -179,7 +179,7 @@ } IN_PROC_BROWSER_TEST_F(AppListClientImplBrowserTest, ShowAppInfo) { - web_app::SystemWebAppManager::GetForTest(profile()) + ash::SystemWebAppManager::GetForTest(profile()) ->InstallSystemAppsForTesting(); AppListClientImpl* client = AppListClientImpl::GetInstance();
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item_browsertest.cc b/chrome/browser/ui/app_list/app_service/app_service_app_item_browsertest.cc index 0e063ad7..60bbc25 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item_browsertest.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item_browsertest.cc
@@ -17,12 +17,12 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/platform_apps/app_browsertest_util.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_service/app_service_app_item.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/web_applications/web_app_launch_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/with_crosapi_param.h" #include "chrome/browser/web_applications/web_app_id.h" #include "chrome/browser/web_applications/web_app_id_constants.h" @@ -269,8 +269,7 @@ IN_PROC_BROWSER_TEST_P(AppServiceSystemWebAppItemBrowserTest, Activate) { Profile* const profile = browser()->profile(); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); const web_app::AppId app_id = web_app::kHelpAppId; // Wait for app service to see the newly installed apps.
diff --git a/chrome/browser/ui/app_list/search/app_service_app_result.cc b/chrome/browser/ui/app_list/search/app_service_app_result.cc index a835d92f..92f50fe 100644 --- a/chrome/browser/ui/app_list/search/app_service_app_result.cc +++ b/chrome/browser/ui/app_list/search/app_service_app_result.cc
@@ -28,7 +28,6 @@ #include "chrome/browser/ui/app_list/search/common/icon_constants.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/common/chrome_features.h" #include "components/favicon/core/large_icon_service.h" #include "components/services/app_service/public/cpp/app_update.h"
diff --git a/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc b/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc index ddd7683a..e682e66f 100644 --- a/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc +++ b/chrome/browser/ui/app_list/search/help_app_search_browsertest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/apps/app_service/app_launch_params.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/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ui/app_list/search/test/app_list_search_test_helper.h" #include "chrome/browser/ui/app_list/search/test/search_results_changed_waiter.h" #include "chrome/browser/ui/app_list/search/test/test_continue_files_search_provider.h" @@ -20,7 +21,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/web_app_launch_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/with_crosapi_param.h" #include "chrome/browser/web_applications/web_app_id.h" @@ -134,7 +134,7 @@ // the Discover page. IN_PROC_BROWSER_TEST_P(HelpAppSearchBrowserTest, ClickingDiscoverTabSuggestionChipLaunchesHelpApp) { - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); GetProfile()->GetPrefs()->SetInteger( prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 3); @@ -179,7 +179,7 @@ // left to show it. IN_PROC_BROWSER_TEST_P(HelpAppSearchBrowserTest, AppListSearchHasReleaseNotesSuggestionChip) { - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); GetProfile()->GetPrefs()->SetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3); @@ -204,7 +204,7 @@ // the chip is shown. IN_PROC_BROWSER_TEST_P(HelpAppSearchBrowserTest, ReleaseNotesDecreasesTimesShownOnAppListOpen) { - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); GetProfile()->GetPrefs()->SetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3); @@ -230,7 +230,7 @@ IN_PROC_BROWSER_TEST_P( HelpAppSearchBrowserTest, ReleaseNotesDecreasesTimesShownOnAppListOpenInTabletMode) { - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); GetProfile()->GetPrefs()->SetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3); @@ -262,7 +262,7 @@ // the What's New page. IN_PROC_BROWSER_TEST_P(HelpAppSearchBrowserTest, ClickingReleaseNotesSuggestionChipLaunchesHelpApp) { - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); GetProfile()->GetPrefs()->SetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3); @@ -301,7 +301,7 @@ IN_PROC_BROWSER_TEST_P(HelpAppSearchBrowserTest, HelpAppProviderProvidesListResults) { // Need this because it sets up the icon. - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); // Add some searchable content to the help app search handler. std::vector<ash::help_app::mojom::SearchConceptPtr> search_concepts; @@ -378,7 +378,7 @@ // Test that Help App shows up normally even when suggestion chip should show. IN_PROC_BROWSER_TEST_P(HelpAppSwaSearchBrowserTest, AppListSearchHasApp) { - web_app::SystemWebAppManager::GetForTest(GetProfile()) + ash::SystemWebAppManager::GetForTest(GetProfile()) ->InstallSystemAppsForTesting(); GetProfile()->GetPrefs()->SetInteger( prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3); @@ -399,8 +399,7 @@ IN_PROC_BROWSER_TEST_P(HelpAppSwaSearchBrowserTest, Launch) { Profile* profile = browser()->profile(); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); const web_app::AppId app_id = web_app::kHelpAppId; ShowAppListAndWaitForZeroStateResults(
diff --git a/chrome/browser/ui/app_list/search/personalization_provider.cc b/chrome/browser/ui/app_list/search/personalization_provider.cc index cd00260..cdfe506 100644 --- a/chrome/browser/ui/app_list/search/personalization_provider.cc +++ b/chrome/browser/ui/app_list/search/personalization_provider.cc
@@ -20,13 +20,13 @@ #include "base/metrics/histogram_functions.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/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_manager_factory.h" #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_metrics.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/common/icon_constants.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/ui/ash/arc_open_url_delegate_impl_browsertest.cc b/chrome/browser/ui/ash/arc_open_url_delegate_impl_browsertest.cc index f203fe1..ffbd55df 100644 --- a/chrome/browser/ui/ash/arc_open_url_delegate_impl_browsertest.cc +++ b/chrome/browser/ui/ash/arc_open_url_delegate_impl_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/chromeos/arc/arc_web_contents_data.h" #include "chrome/browser/profiles/profile_manager.h" @@ -19,7 +20,6 @@ #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -100,7 +100,7 @@ const GURL& expected_url, size_t expected_setting_window_count) { // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser->profile()) + ash::SystemWebAppManager::GetForTest(browser->profile()) ->InstallSystemAppsForTesting(); ArcOpenUrlDelegateImpl::GetForTesting()->OpenChromePageFromArc(page); @@ -378,7 +378,7 @@ IN_PROC_BROWSER_TEST_F(ArcOpenUrlDelegateImplBrowserTest, TestOpenChromePage) { // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); TestAllOSSettingPages(GURL(chrome::kChromeUIOSSettingsURL));
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc index cb95481..68e834c 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/file_manager/url_util.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/web_applications/calculator_app/calculator_app_utils.h" #include "chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_delegate.h" #include "chrome/browser/chromeos/arc/arc_web_contents_data.h" @@ -57,7 +58,6 @@ #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_id.h" #include "chrome/browser/web_applications/web_app_id_constants.h" @@ -536,7 +536,7 @@ bool ChromeNewWindowClient::IsCameraAppEnabled() { Profile* const profile = ProfileManager::GetActiveUserProfile(); - auto* swa_manager = web_app::SystemWebAppManager::Get(profile); + auto* swa_manager = ash::SystemWebAppManager::Get(profile); return swa_manager && swa_manager->IsAppEnabled(ash::SystemWebAppType::CAMERA); }
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 5fee4c74..35c12448 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -49,7 +49,6 @@ #include "chrome/browser/ui/views/tabs/tab_scrubber_chromeos.h" #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.h" #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_switches.h" #include "components/ui_devtools/devtools_server.h"
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc index 1ba5efb1..1ff89e1 100644 --- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc +++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/ash/login/test/login_manager_mixin.h" #include "chrome/browser/ash/login/ui/user_adding_screen.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/policy/policy_test_utils.h" #include "chrome/browser/prefs/session_startup_pref.h" @@ -55,7 +56,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -436,7 +436,7 @@ // extensions::PlatformAppBrowserTest: void SetUpOnMainThread() override { ::full_restore::SetActiveProfilePath(profile()->GetPath()); - web_app::SystemWebAppManager::GetForTest(profile()) + ash::SystemWebAppManager::GetForTest(profile()) ->InstallSystemAppsForTesting(); extensions::PlatformAppBrowserTest::SetUpOnMainThread(); }
diff --git a/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc b/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc index 1a95a922..e33ed88 100644 --- a/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc +++ b/chrome/browser/ui/ash/desks/desks_templates_app_launch_handler.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ash/app_restore/app_launch_handler.h" #include "chrome/browser/ash/app_restore/app_restore_arc_task_handler.h" #include "chrome/browser/ash/app_restore/arc_app_launch_handler.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/desks/desks_client.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h" @@ -24,7 +25,6 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "components/app_constants/constants.h" #include "components/app_restore/app_restore_data.h" @@ -120,7 +120,7 @@ web_app::GetSystemWebAppTypeForAppId(profile(), app_id); if (swa_type.has_value()) { auto* system_app = - web_app::SystemWebAppManager::Get(profile())->GetSystemApp(*swa_type); + ash::SystemWebAppManager::Get(profile())->GetSystemApp(*swa_type); DCHECK(system_app); is_multi_instance_window = system_app->ShouldShowNewWindowMenuOption(); }
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc index 82a1f223..281ae38 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -13,6 +13,7 @@ #include "ash/webui/projector_app/projector_app_client.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" #include "base/bind.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_prefs.h" @@ -22,7 +23,6 @@ #include "chrome/browser/ui/ash/projector/projector_utils.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chromeos/login/login_state/login_state.h" @@ -270,8 +270,8 @@ void ProjectorClientImpl::OnEnablementPolicyChanged() { Profile* profile = ProfileManager::GetActiveUserProfile(); - web_app::SystemWebAppManager* swa_manager = - web_app::SystemWebAppManager::Get(profile); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::Get(profile); const bool is_installed = swa_manager && swa_manager->IsSystemWebApp(ash::kChromeUITrustedProjectorSwaAppId);
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc index c3fdafd2..082acb90 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ash/drive/drivefs_test_support.h" #include "chrome/browser/ash/login/test/fake_gaia_mixin.h" #include "chrome/browser/ash/login/test/logged_in_user_mixin.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/projector/projector_app_client_impl.h" @@ -30,7 +31,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_id.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/test/base/in_process_browser_test.h" @@ -183,8 +183,7 @@ IN_PROC_BROWSER_TEST_F(ProjectorClientTest, OpenProjectorApp) { auto* profile = browser()->profile(); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); client()->OpenProjectorApp(); web_app::FlushSystemWebAppLaunchesForTesting(profile); @@ -202,8 +201,7 @@ IN_PROC_BROWSER_TEST_F(ProjectorClientTest, MinimizeProjectorApp) { auto* profile = browser()->profile(); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); client()->OpenProjectorApp(); web_app::FlushSystemWebAppLaunchesForTesting(profile); @@ -225,8 +223,7 @@ IN_PROC_BROWSER_TEST_F(ProjectorClientTest, CloseProjectorApp) { auto* profile = browser()->profile(); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); client()->OpenProjectorApp(); web_app::FlushSystemWebAppLaunchesForTesting(profile); @@ -338,8 +335,7 @@ IN_PROC_BROWSER_TEST_P(ProjectorClientManagedTest, CantOpenProjectorAppWithoutPolicy) { auto* profile = browser()->profile(); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); client()->OpenProjectorApp(); web_app::FlushSystemWebAppLaunchesForTesting(profile); @@ -354,8 +350,7 @@ IN_PROC_BROWSER_TEST_P(ProjectorClientManagedTest, DisableThenEnablePolicy) { auto* profile = browser()->profile(); profile->GetPrefs()->SetBoolean(GetPolicy(), true); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); client()->OpenProjectorApp(); web_app::FlushSystemWebAppLaunchesForTesting(profile);
diff --git a/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc b/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc index 20b70e7d..9e68a99 100644 --- a/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h" #include "chrome/browser/apps/intent_helper/common_apps_navigation_throttle.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/browser.h" @@ -20,7 +21,6 @@ #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" @@ -58,7 +58,7 @@ void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); - web_app::SystemWebAppManager::GetForTest(profile()) + ash::SystemWebAppManager::GetForTest(profile()) ->InstallSystemAppsForTesting(); base::Time start_time; @@ -279,7 +279,7 @@ void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); - web_app::SystemWebAppManager::GetForTest(profile()) + ash::SystemWebAppManager::GetForTest(profile()) ->InstallSystemAppsForTesting(); }
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc index 6b65de2..f829a70 100644 --- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/ash/borealis/borealis_window_manager_mock.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" @@ -35,7 +36,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/with_crosapi_param.h" #include "chrome/browser/web_applications/web_app_id_constants.h" @@ -936,7 +936,7 @@ IN_PROC_BROWSER_TEST_P(AppServiceAppWindowSystemWebAppBrowserTest, SystemWebAppWindow) { - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); const std::string app_id = web_app::kOsSettingsAppId;
diff --git a/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc index 74d8f173..6c1b178 100644 --- a/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller_browsertest.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/shelf_types.h" #include "base/callback_helpers.h" #include "chrome/browser/ash/crostini/crostini_terminal.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h" #include "chrome/browser/ui/browser.h" @@ -17,7 +18,6 @@ #include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" @@ -64,7 +64,7 @@ } void InstallApp() { - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); app_id_ = *web_app::GetAppIdForSystemWebApp(
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc index 84cc069..17680766 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -55,6 +55,7 @@ #include "chrome/browser/ash/file_manager/app_id.h" #include "chrome/browser/ash/file_manager/file_manager_test_util.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" @@ -89,7 +90,6 @@ #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "chrome/browser/web_applications/policy/web_app_policy_constants.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/service_worker_registration_waiter.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/test/web_app_test_observers.h" @@ -2217,7 +2217,7 @@ // icon's context menu works as expected. IN_PROC_BROWSER_TEST_F(ShelfAppBrowserTest, CloseSystemAppByShelfContextMenu) { // Prepare for launching the setting app. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); // Record the default shelf item count. @@ -2393,7 +2393,7 @@ // Ensure opening settings and task manager windows create new shelf items. IN_PROC_BROWSER_TEST_F(ShelfWebAppBrowserTest, SettingsAndTaskManagerWindows) { // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); chrome::SettingsWindowManager* settings_manager = chrome::SettingsWindowManager::GetInstance(); @@ -3112,7 +3112,7 @@ void WaitForSystemAppsSynchronized() { base::RunLoop run_loop; - web_app::SystemWebAppManager::Get(browser()->profile()) + ash::SystemWebAppManager::Get(browser()->profile()) ->on_apps_synchronized() .Post(FROM_HERE, run_loop.QuitClosure()); run_loop.Run();
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc index 468eadc..e494283 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -104,7 +104,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/externally_installed_web_app_prefs.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
diff --git a/chrome/browser/ui/autofill_assistant/password_change/password_change_run_controller.h b/chrome/browser/ui/autofill_assistant/password_change/password_change_run_controller.h index 13758f5..f7b57e9 100644 --- a/chrome/browser/ui/autofill_assistant/password_change/password_change_run_controller.h +++ b/chrome/browser/ui/autofill_assistant/password_change/password_change_run_controller.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/memory/weak_ptr.h" #include "chrome/browser/autofill_assistant/password_change/proto/extensions.pb.h" class PasswordChangeRunDisplay; @@ -15,6 +16,16 @@ // Abstract interface for a controller of an `PasswordChangeRunDisplay`. class PasswordChangeRunController { public: + // Defines the current UI state to restore pre-interrupt UI. + // Interrupts are not triggered during prompts, therefore + // there is no need to keep their state. + struct Model { + std::u16string title; + autofill_assistant::password_change::TopIcon top_icon; + std::u16string progress_description; + autofill_assistant::password_change::ProgressStep progress_step; + }; + // Factory function to create the controller. static std::unique_ptr<PasswordChangeRunController> Create();
diff --git a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc index 69121b4..373c330 100644 --- a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc +++ b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc
@@ -45,7 +45,7 @@ #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #endif @@ -254,7 +254,7 @@ #endif IN_PROC_BROWSER_TEST_F(FramebustBlockBrowserTest, MAYBE_ManageButtonClicked) { #if BUILDFLAG(IS_CHROMEOS_ASH) - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); #endif
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc index f0404c9..7341f307 100644 --- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc +++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -29,7 +29,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc index 3436fc3..fd4bc53 100644 --- a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/apps/app_service/browser_app_launcher.h" #include "chrome/browser/ash/login/test/login_manager_mixin.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -18,7 +19,6 @@ #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" @@ -52,7 +52,7 @@ void SetUpOnMainThread() override { // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); }
diff --git a/chrome/browser/ui/settings_window_manager_chromeos.cc b/chrome/browser/ui/settings_window_manager_chromeos.cc index a13b548..7c3fd78 100644 --- a/chrome/browser/ui/settings_window_manager_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_chromeos.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" #include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/apps/app_service/launch_utils.h" +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/window_properties.h" #include "chrome/browser/ui/browser.h" @@ -20,7 +21,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/common/webui_url_constants.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/startup/lacros_first_run_service.cc b/chrome/browser/ui/startup/lacros_first_run_service.cc index 43726ac..4d5f5ae9 100644 --- a/chrome/browser/ui/startup/lacros_first_run_service.cc +++ b/chrome/browser/ui/startup/lacros_first_run_service.cc
@@ -96,6 +96,9 @@ // we get all the way here, we assume that we can proceed with it. std::move(callback).Run(LoginUIService::SyncConfirmationUIClosedResult:: SYNC_WITH_DEFAULT_SETTINGS); + + ProfileMetrics::LogLacrosPrimaryProfileFirstRunOutcome( + ProfileMetrics::ProfileSignedInFlowOutcome::kSkippedByPolicies); } void ShowSyncDisabledConfirmation( @@ -105,6 +108,9 @@ // `SYNC_WITH_DEFAULT_SETTINGS` for the sync disable confirmation means // "stay signed in". See https://crbug.com/1141341. std::move(callback).Run(LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); + + ProfileMetrics::LogLacrosPrimaryProfileFirstRunOutcome( + ProfileMetrics::ProfileSignedInFlowOutcome::kSkippedByPolicies); } void ShowLoginError(const SigninUIError& error) override { NOTREACHED(); } @@ -225,6 +231,8 @@ auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)) { + ProfileMetrics::LogLacrosPrimaryProfileFirstRunOutcome( + ProfileMetrics::ProfileSignedInFlowOutcome::kSkippedAlreadySyncing); SetFirstRunFinished(); return; }
diff --git a/chrome/browser/ui/startup/lacros_first_run_service_browsertest.cc b/chrome/browser/ui/startup/lacros_first_run_service_browsertest.cc index 159e852..b8b876c 100644 --- a/chrome/browser/ui/startup/lacros_first_run_service_browsertest.cc +++ b/chrome/browser/ui/startup/lacros_first_run_service_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/ui/startup/lacros_first_run_service.h" #include "base/callback_forward.h" @@ -86,10 +88,10 @@ // is opened to simplify the setup. This allows us to call FRE-related methods // without having to do more elaborate things to avoid it triggering before // the test starts. - EXPECT_FALSE(fre_service()->ShouldOpenFirstRun()); base::CommandLine::ForCurrentProcess()->RemoveSwitch(switches::kNoFirstRun); EXPECT_TRUE(fre_service()->ShouldOpenFirstRun()); + base::HistogramTester histogram_tester; base::RunLoop run_loop; fre_service()->TryMarkFirstRunAlreadyFinished(run_loop.QuitClosure()); @@ -98,6 +100,8 @@ EXPECT_FALSE(g_browser_process->local_state()->GetBoolean( lacros_prefs::kPrimaryProfileFirstRunFinished)); EXPECT_TRUE(fre_service()->ShouldOpenFirstRun()); + histogram_tester.ExpectTotalCount( + "Profile.LacrosPrimaryProfileFirstRunOutcome", 0); } IN_PROC_BROWSER_TEST_F(LacrosFirstRunServiceBrowserTest, @@ -111,6 +115,7 @@ ASSERT_FALSE(account_id.empty()); identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount( account_id, signin::ConsentLevel::kSync); + base::HistogramTester histogram_tester; base::RunLoop run_loop; fre_service()->TryMarkFirstRunAlreadyFinished(run_loop.QuitClosure()); @@ -119,6 +124,9 @@ EXPECT_TRUE(g_browser_process->local_state()->GetBoolean( lacros_prefs::kPrimaryProfileFirstRunFinished)); EXPECT_FALSE(fre_service()->ShouldOpenFirstRun()); + histogram_tester.ExpectUniqueSample( + "Profile.LacrosPrimaryProfileFirstRunOutcome", + ProfileMetrics::ProfileSignedInFlowOutcome::kSkippedAlreadySyncing, 1); } IN_PROC_BROWSER_TEST_F(LacrosFirstRunServiceBrowserTest, @@ -126,6 +134,7 @@ base::CommandLine::ForCurrentProcess()->RemoveSwitch(switches::kNoFirstRun); signin::IdentityManager* identity_manager = identity_test_env()->identity_manager(); + base::HistogramTester histogram_tester; testing::ScopedSyncRequiredInFirstRun sync_required_override{true}; @@ -137,6 +146,9 @@ lacros_prefs::kPrimaryProfileFirstRunFinished)); EXPECT_FALSE(fre_service()->ShouldOpenFirstRun()); EXPECT_TRUE(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)); + histogram_tester.ExpectUniqueSample( + "Profile.LacrosPrimaryProfileFirstRunOutcome", + ProfileMetrics::ProfileSignedInFlowOutcome::kSkippedByPolicies, 1); } IN_PROC_BROWSER_TEST_F(LacrosFirstRunServiceBrowserTest, @@ -145,6 +157,7 @@ Profile* profile = browser()->profile(); signin::IdentityManager* identity_manager = identity_test_env()->identity_manager(); + base::HistogramTester histogram_tester; profile->GetPrefs()->SetBoolean(prefs::kEnableSyncConsent, false); @@ -156,4 +169,7 @@ lacros_prefs::kPrimaryProfileFirstRunFinished)); EXPECT_FALSE(ShouldOpenPrimaryProfileFirstRun(profile)); EXPECT_TRUE(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)); + histogram_tester.ExpectUniqueSample( + "Profile.LacrosPrimaryProfileFirstRunOutcome", + ProfileMetrics::ProfileSignedInFlowOutcome::kSkippedByPolicies, 1); }
diff --git a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc index af9ffd6..d7bfec1 100644 --- a/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc +++ b/chrome/browser/ui/tab_contents/chrome_web_contents_view_handle_drop_unittest.cc
@@ -79,8 +79,6 @@ run_loop_ = std::make_unique<base::RunLoop>(); using FakeDelegate = enterprise_connectors::FakeContentAnalysisDelegate; - auto is_encrypted_callback = - base::BindRepeating([](const base::FilePath&) { return false; }); policy::SetDMTokenForTesting( policy::DMToken::CreateValidTokenForTesting("dm_token")); @@ -101,8 +99,7 @@ enterprise_connectors::ContentAnalysisDelegate::SetFactoryForTesting( base::BindRepeating( &enterprise_connectors::FakeContentAnalysisDelegate::Create, - run_loop_->QuitClosure(), callback, is_encrypted_callback, - "dm_token")); + run_loop_->QuitClosure(), callback, "dm_token")); enterprise_connectors::ContentAnalysisDelegate::DisableUIForTesting(); }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc index ff7caec..8727cf2 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
@@ -13,6 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/apps/app_info_dialog.h" @@ -24,7 +25,6 @@ #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h" #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_switches.h" @@ -69,7 +69,7 @@ bool CanShowAppInfoDialog(Profile* profile, const std::string& extension_id) { #if BUILDFLAG(IS_CHROMEOS_ASH) bool is_system_web_app = - web_app::SystemWebAppManager::Get(profile)->IsSystemWebApp(extension_id); + ash::SystemWebAppManager::Get(profile)->IsSystemWebApp(extension_id); if (is_system_web_app) { return false; }
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc index 593b37a0..42e95fa 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -93,8 +93,8 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/services/multidevice_setup/public/cpp/prefs.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #endif @@ -176,7 +176,7 @@ ASSERT_TRUE(SetupClients()); #if BUILDFLAG(IS_CHROMEOS_ASH) // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(GetProfile(0)) + ash::SystemWebAppManager::GetForTest(GetProfile(0)) ->InstallSystemAppsForTesting(); #endif
diff --git a/chrome/browser/ui/views/crostini/crostini_recovery_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_recovery_view_browsertest.cc index a4e368e..3b2f381 100644 --- a/chrome/browser/ui/views/crostini/crostini_recovery_view_browsertest.cc +++ b/chrome/browser/ui/views/crostini/crostini_recovery_view_browsertest.cc
@@ -14,11 +14,11 @@ #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/crostini/crostini_dialogue_browser_test_util.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -141,7 +141,7 @@ SetUncleanStartup(); RegisterApp(); // Ensure Terminal System App is installed. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); // First app should fail with 'cancelled for recovery'.
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.cc b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.cc index 6a82a43..9638af1 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.cc +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.cc
@@ -6,11 +6,15 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_frame.h" +#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chromeos/ui/base/window_properties.h" +#include "ui/compositor/layer.h" #include "ui/platform_window/extensions/wayland_extension.h" +#include "ui/platform_window/platform_window.h" +#include "ui/views/layout/layout_provider.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" //////////////////////////////////////////////////////////////////////////////// @@ -36,6 +40,82 @@ BrowserDesktopWindowTreeHostLacros::~BrowserDesktopWindowTreeHostLacros() = default; +void BrowserDesktopWindowTreeHostLacros::UpdateFrameHints() { + auto* const view = browser_view_->frame()->GetFrameView(); + const bool showing_frame = + browser_view_->frame()->UseCustomFrame() && !view->IsFrameCondensed(); + const float scale = device_scale_factor(); + const gfx::Size widget_size = + view->GetWidget()->GetWindowBoundsInScreen().size(); + + std::vector<gfx::Rect> opaque_region; + if (showing_frame) { + float corner_radius = views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::Emphasis::kHigh); + GetContentWindow()->layer()->SetRoundedCornerRadius( + gfx::RoundedCornersF(corner_radius, corner_radius, 0, 0)); + GetContentWindow()->layer()->SetIsFastRoundedCorner(true); + + // The opaque region is a list of rectangles that contain only fully + // opaque pixels of the window. We need to convert the clipping + // rounded-rect into this format. + const SkVector radii[4]{ + {corner_radius, corner_radius}, {corner_radius, corner_radius}, {}, {}}; + SkRRect rrect; + rrect.setRectRadii(gfx::RectToSkRect(view->GetLocalBounds()), radii); + gfx::RectF rectf = gfx::SkRectToRectF(rrect.rect()); + rectf.Scale(scale); + // It is acceptable to omit some pixels that are opaque, but the region + // must not include any translucent pixels. Therefore, we must + // conservatively scale to the enclosed rectangle. + gfx::Rect rect = gfx::ToEnclosedRect(rectf); + + // Create the initial region from the clipping rectangle without rounded + // corners. + SkRegion region(gfx::RectToSkIRect(rect)); + + // Now subtract out the small rectangles that cover the corners. + struct { + SkRRect::Corner corner; + bool left; + bool upper; + } kCorners[] = { + {SkRRect::kUpperLeft_Corner, true, true}, + {SkRRect::kUpperRight_Corner, false, true}, + {SkRRect::kLowerLeft_Corner, true, false}, + {SkRRect::kLowerRight_Corner, false, false}, + }; + for (const auto& corner : kCorners) { + auto radii = rrect.radii(corner.corner); + auto rx = std::ceil(scale * radii.x()); + auto ry = std::ceil(scale * radii.y()); + auto corner_rect = SkIRect::MakeXYWH( + corner.left ? rect.x() : rect.right() - rx, + corner.upper ? rect.y() : rect.bottom() - ry, rx, ry); + region.op(corner_rect, SkRegion::kDifference_Op); + } + + // Convert the region to a list of rectangles. + for (SkRegion::Iterator i(region); !i.done(); i.next()) + opaque_region.push_back(gfx::SkIRectToRect(i.rect())); + } else { + GetContentWindow()->layer()->SetRoundedCornerRadius({}); + GetContentWindow()->layer()->SetIsFastRoundedCorner(false); + opaque_region.push_back({{}, widget_size}); + } + platform_window()->SetOpaqueRegion(&opaque_region); +} + +//////////////////////////////////////////////////////////////////////////////// +// BrowserDesktopWindowTreeHostLacros, +// DesktopWindowTreeHost implementation: + +void BrowserDesktopWindowTreeHostLacros::OnWidgetInitDone() { + DesktopWindowTreeHostLacros::OnWidgetInitDone(); + + UpdateFrameHints(); +} + //////////////////////////////////////////////////////////////////////////////// // BrowserDesktopWindowTreeHostLacros, // BrowserDesktopWindowTreeHost implementation: @@ -90,6 +170,13 @@ } } +void BrowserDesktopWindowTreeHostLacros::OnBoundsChanged( + const BoundsChange& change) { + DesktopWindowTreeHostLacros::OnBoundsChanged(change); + + UpdateFrameHints(); +} + void BrowserDesktopWindowTreeHostLacros::OnWindowStateChanged( ui::PlatformWindowState old_window_show_state, ui::PlatformWindowState new_window_show_state) { @@ -104,6 +191,8 @@ // BrowserView::ProcessFullscreen will no-op, so this call is harmless. browser_view_->FullscreenStateChanging(); } + + UpdateFrameHints(); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.h b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.h index a277c4a..faeef7d 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.h +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_lacros.h
@@ -35,6 +35,12 @@ void TabDraggingKindChanged(TabDragKind tab_drag_kind); private: + // Sets hints for the WM/compositor that reflect the rounded corners. + void UpdateFrameHints(); + + // DesktopWindowTreeHost: + void OnWidgetInitDone() override; + // BrowserDesktopWindowTreeHost: DesktopWindowTreeHost* AsDesktopWindowTreeHost() override; int GetMinimizeButtonOffset() const override; @@ -48,6 +54,7 @@ void UnlockMouse(aura::Window* window) override; // ui::PlatformWindowDelegate + void OnBoundsChanged(const BoundsChange& change) override; void OnWindowStateChanged(ui::PlatformWindowState old_state, ui::PlatformWindowState new_state) override;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc index 672ee45..c187010b 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -49,6 +49,7 @@ #include "base/test/test_future.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/profiles/profile_io_data.h" @@ -87,7 +88,6 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" @@ -581,7 +581,7 @@ IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewChromeOSTest, SettingsSystemWebAppHasMinimumWindowSize) { // Install the Settings System Web App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); // Open a settings window.
diff --git a/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest_chromeos.cc b/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest_chromeos.cc index 5fd657a..1e25a6d 100644 --- a/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest_chromeos.cc +++ b/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest_chromeos.cc
@@ -8,10 +8,10 @@ #include "chrome/browser/ash/login/test/login_manager_mixin.h" #include "chrome/browser/ash/login/ui/user_adding_screen.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "components/account_id/account_id.h" #include "components/user_manager/user_manager.h" @@ -52,8 +52,7 @@ // Install the Settings App. Profile* profile = ProfileHelper::Get()->GetProfileByUser( UserManager::Get()->FindUser(account_id1_)); - web_app::SystemWebAppManager::GetForTest(profile) - ->InstallSystemAppsForTesting(); + ash::SystemWebAppManager::GetForTest(profile)->InstallSystemAppsForTesting(); // Open the settings window and record the |settings_browser|. auto* manager = SettingsWindowManager::GetInstance();
diff --git a/chrome/browser/ui/views/frame/system_web_app_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/system_web_app_non_client_frame_view_browsertest.cc index 02564f1c..e92b790d 100644 --- a/chrome/browser/ui/views/frame/system_web_app_non_client_frame_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/system_web_app_non_client_frame_view_browsertest.cc
@@ -8,12 +8,15 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" +#if !BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" +#endif + using SystemWebAppNonClientFrameViewBrowserTest = web_app::SystemWebAppManagerBrowserTest;
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_browsertest.cc index 9a2d841..e2b59a8c 100644 --- a/chrome/browser/ui/views/payments/payment_request_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_browsertest.cc
@@ -27,7 +27,7 @@ #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #endif @@ -617,7 +617,7 @@ IN_PROC_BROWSER_TEST_F(PaymentRequestSettingsLinkTest, ClickSettingsLink) { #if BUILDFLAG(IS_CHROMEOS_ASH) // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); #endif @@ -671,7 +671,7 @@ ClickSettingsLink) { #if BUILDFLAG(IS_CHROMEOS_ASH) // Install the Settings App. - web_app::SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); #endif
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc index 8fbe0d9..ed46393 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -1866,7 +1866,8 @@ WaitForPickerClosed(); EXPECT_EQ(0u, BrowserList::GetInstance()->size()); EXPECT_TRUE(ShouldOpenPrimaryProfileFirstRun(profile)); - histogram_tester.ExpectBucketCount( + + histogram_tester.ExpectUniqueSample( "Profile.LacrosPrimaryProfileFirstRunOutcome", ProfileMetrics::ProfileSignedInFlowOutcome::kAbortedOnEnterpriseWelcome, 1); @@ -1915,7 +1916,7 @@ // Because we quit, we should also quit chrome, but mark the FRE finished. EXPECT_FALSE(ShouldOpenPrimaryProfileFirstRun(profile)); EXPECT_EQ(0u, BrowserList::GetInstance()->size()); - histogram_tester.ExpectBucketCount( + histogram_tester.ExpectUniqueSample( "Profile.LacrosPrimaryProfileFirstRunOutcome", ProfileMetrics::ProfileSignedInFlowOutcome::kAbortedAfterSignIn, 1); } @@ -1963,7 +1964,7 @@ WaitForPickerClosed(); EXPECT_FALSE(ShouldOpenPrimaryProfileFirstRun(profile)); EXPECT_EQ(1u, BrowserList::GetInstance()->size()); - histogram_tester.ExpectBucketCount( + histogram_tester.ExpectUniqueSample( "Profile.LacrosPrimaryProfileFirstRunOutcome", ProfileMetrics::ProfileSignedInFlowOutcome::kConsumerSync, 1); }
diff --git a/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc b/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc index d1748fe..d34520c 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_install_info.h"
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc index 9bbaac9..310aa52 100644 --- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc +++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/launch_utils.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_navigator.h" @@ -24,7 +25,6 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/web_app_launch_manager.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" @@ -87,14 +87,14 @@ absl::optional<ash::SystemWebAppType> GetSystemWebAppTypeForAppId( Profile* profile, const AppId& app_id) { - auto* swa_manager = SystemWebAppManager::Get(profile); + auto* swa_manager = ash::SystemWebAppManager::Get(profile); return swa_manager ? swa_manager->GetSystemAppTypeForAppId(app_id) : absl::nullopt; } absl::optional<AppId> GetAppIdForSystemWebApp(Profile* profile, ash::SystemWebAppType app_type) { - auto* swa_manager = SystemWebAppManager::Get(profile); + auto* swa_manager = ash::SystemWebAppManager::Get(profile); return swa_manager ? swa_manager->GetAppIdForSystemApp(app_type) : absl::nullopt; } @@ -199,7 +199,8 @@ return nullptr; } - SystemWebAppManager* swa_manager = SystemWebAppManager::Get(profile); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::Get(profile); if (!swa_manager) return nullptr; @@ -315,7 +316,8 @@ absl::optional<ash::SystemWebAppType> GetCapturingSystemAppForURL( Profile* profile, const GURL& url) { - SystemWebAppManager* swa_manager = SystemWebAppManager::Get(profile); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::Get(profile); return swa_manager ? swa_manager->GetCapturingSystemAppForURL(url) : absl::nullopt; }
diff --git a/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc b/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc index 24c3b10..bbbf87386 100644 --- a/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc +++ b/chrome/browser/ui/web_applications/test/system_web_app_interactive_uitest.cc
@@ -16,6 +16,7 @@ #include "build/chromeos_buildflags.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" #include "chrome/browser/ui/app_list/app_service/app_service_app_item.h" #include "chrome/browser/ui/browser_finder.h" @@ -530,7 +531,7 @@ void WaitForSystemWebAppInstall(Profile* profile) { base::RunLoop run_loop; - web_app::SystemWebAppManager::Get(profile)->on_apps_synchronized().Post( + ash::SystemWebAppManager::Get(profile)->on_apps_synchronized().Post( FROM_HERE, base::BindLambdaForTesting([&]() { // Wait one execution loop for // on_apps_synchronized() to be called on all @@ -543,7 +544,7 @@ AppId GetAppId(Profile* profile) { absl::optional<AppId> app_id = - web_app::SystemWebAppManager::Get(profile)->GetAppIdForSystemApp( + ash::SystemWebAppManager::Get(profile)->GetAppIdForSystemApp( installation_->GetType()); CHECK(app_id.has_value()); return *app_id;
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc index 1001b0d..8d069e8 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -13,6 +13,7 @@ #include "build/chromeos_buildflags.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/ash/system_web_apps/types/system_web_app_delegate.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -21,7 +22,6 @@ #include "chrome/browser/ui/web_applications/web_app_dialog_manager.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" #include "chrome/browser/ui/web_applications/web_app_ui_manager_impl.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.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_icon_manager.h"
diff --git a/chrome/browser/ui/web_applications/web_app_guest_session_browsertest_chromeos.cc b/chrome/browser/ui/web_applications/web_app_guest_session_browsertest_chromeos.cc index d741a87..1b72ee9 100644 --- a/chrome/browser/ui/web_applications/web_app_guest_session_browsertest_chromeos.cc +++ b/chrome/browser/ui/web_applications/web_app_guest_session_browsertest_chromeos.cc
@@ -7,8 +7,8 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/browser_app_launcher.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/with_crosapi_param.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -41,7 +41,7 @@ // Test that the OS Settings app launches successfully. IN_PROC_BROWSER_TEST_P(WebAppGuestSessionBrowserTest, LaunchOsSettings) { - SystemWebAppManager::GetForTest(browser()->profile()) + ash::SystemWebAppManager::GetForTest(browser()->profile()) ->InstallSystemAppsForTesting(); Profile* profile = browser()->profile();
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.cc b/chrome/browser/ui/web_applications/web_app_launch_process.cc index b7b9e01..85ecfdb8e 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_process.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_process.cc
@@ -36,7 +36,7 @@ #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS) -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #endif namespace web_app { @@ -89,10 +89,10 @@ // DCHECK on the basic scope. DCHECK(provider_.registrar().IsUrlInAppScope(launch_url, params_.app_id) || GetSystemWebAppTypeForAppId(&profile_, params_.app_id) && - SystemWebAppManager::GetForLocalAppsUnchecked(&profile_) + ash::SystemWebAppManager::GetForLocalAppsUnchecked(&profile_) ->GetSystemApp( *GetSystemWebAppTypeForAppId(&profile_, params_.app_id)) && - SystemWebAppManager::GetForLocalAppsUnchecked(&profile_) + ash::SystemWebAppManager::GetForLocalAppsUnchecked(&profile_) ->GetSystemApp( *GetSystemWebAppTypeForAppId(&profile_, params_.app_id)) ->IsUrlInSystemAppScope(launch_url));
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc index 8552077a..07b3ca2 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -19,6 +19,7 @@ #include "build/buildflag.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/app_mode/app_mode_utils.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/app_session_service.h" #include "chrome/browser/sessions/app_session_service_factory.h" @@ -35,7 +36,6 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/web_app_browser_controller.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.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_install_utils.h" @@ -227,7 +227,7 @@ GetSystemWebAppTypeForAppId(browser->profile(), app_id); if (system_app_type) { system_app = - SystemWebAppManager::GetForLocalAppsUnchecked(browser->profile()) + ash::SystemWebAppManager::GetForLocalAppsUnchecked(browser->profile()) ->GetSystemApp(*system_app_type); } const bool has_tab_strip = @@ -309,8 +309,8 @@ WebAppProvider* web_app_provider = WebAppProvider::GetForLocalAppsUnchecked(browser->profile()); DCHECK(web_app_provider); - SystemWebAppManager* swa_manager = - SystemWebAppManager::GetForLocalAppsUnchecked(browser->profile()); + ash::SystemWebAppManager* swa_manager = + ash::SystemWebAppManager::GetForLocalAppsUnchecked(browser->profile()); DCHECK(swa_manager); TRACE_EVENT_INSTANT(
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc index cad95178..25ee954 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/ui/webui/web_app_internals/web_app_internals_source.h" #include "chrome/browser/web_applications/extensions/web_app_extension_shortcut.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app_callback_app_identity.h" #include "chrome/browser/web_applications/web_app_provider.h"
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc index 51fbdbe2..83a6f46 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/test/fake_os_integration_manager.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 364fad4..b204569 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -127,6 +127,7 @@ #include "components/feed/buildflags.h" #include "components/feed/feed_feature_list.h" #else // BUILDFLAG(IS_ANDROID) +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/media/router/discovery/access_code/access_code_cast_feature.h" #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/ui/ui_features.h" @@ -163,7 +164,6 @@ #include "chrome/browser/ui/webui/tab_search/tab_search_ui.h" #include "chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h" #include "chrome/browser/ui/webui/whats_new/whats_new_ui.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "media/base/media_switches.h" #endif // BUILDFLAG(IS_ANDROID) @@ -1043,7 +1043,7 @@ if (url.host_piece() == chrome::kChromeUIAssistantOptInHost) return &NewWebUI<chromeos::AssistantOptInUI>; if (url.host_piece() == ash::kChromeUICameraAppHost) { - auto* swa_manager = web_app::SystemWebAppManager::Get(profile); + auto* swa_manager = ash::SystemWebAppManager::Get(profile); if (swa_manager && swa_manager->IsAppEnabled(ash::SystemWebAppType::CAMERA)) { return &NewComponentUI<ash::CameraAppUI, ChromeCameraAppUIDelegate>;
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index 4240373..7ac8341 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -161,7 +161,7 @@ const std::string& signin_email, const std::string& signin_gaia_id) { if (!gaia_id_parameter.empty() && - !base::LowerCaseEqualsASCII(gaia_id_parameter, signin_gaia_id)) { + !base::EqualsCaseInsensitiveASCII(gaia_id_parameter, signin_gaia_id)) { return credential_provider::kUiecEMailMissmatch; }
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index bfc1f59..fe5dfb0 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -10,6 +10,8 @@ # TODO(crbug.com/1321984): Extract it to ash/system_web_apps/ "../ash/system_web_apps/system_web_app_background_task.cc", "../ash/system_web_apps/system_web_app_background_task.h", + "../ash/system_web_apps/system_web_app_manager.cc", + "../ash/system_web_apps/system_web_app_manager.h", "app_registrar_observer.h", "commands/callback_command.cc", "commands/callback_command.h", @@ -94,8 +96,6 @@ "preinstalled_web_apps/preinstalled_web_app_definition_utils.h", "preinstalled_web_apps/preinstalled_web_apps.cc", "preinstalled_web_apps/preinstalled_web_apps.h", - "system_web_apps/system_web_app_manager.cc", - "system_web_apps/system_web_app_manager.h", "user_display_mode.cc", "user_display_mode.h", "user_uninstalled_preinstalled_web_app_prefs.cc",
diff --git a/chrome/browser/web_applications/README.md b/chrome/browser/web_applications/README.md index 3017922..7e2d1d2c 100644 --- a/chrome/browser/web_applications/README.md +++ b/chrome/browser/web_applications/README.md
@@ -64,8 +64,8 @@ * `start_url` * `icons` with at least one icon with a valid response that is a parsable image. * `display` field that is not `"browser"` -* "Serviceworker check": The `start_url` is 'controlled' (can be served by) a [serviceworker](https://developers.google.com/web/ilt/pwa/introduction-to-service-worker). **Optionally turned off** -* "Engagement check": The user has engaged with, or interacted with, the page or origin a certain amount (currently at least one click and some seconds on the site). **Optionally turned off** +* "Serviceworker check": The `start_url` is 'controlled' (can be served by) a [serviceworker](https://developers.google.com/web/ilt/pwa/introduction-to-service-worker). **Optionally turned off** +* "Engagement check": The user has engaged with, or interacted with, the page or origin a certain amount (currently at least one click and some seconds on the site). **Optionally turned off** Notes: * Per spec, the document origin and the `start_url` origin must match. @@ -73,7 +73,7 @@ * The `start_url` could be different than the `document_url`. ### Manifest id -The `id` specified in manifest represents the identity of the web app. The manifest id is processed following the algorithm described in [appmanifest specification](https://www.w3.org/TR/appmanifest/#id-member) to produce the app's identity. In web app system, the app's [identity](https://www.w3.org/TR/appmanifest/#dfn-identity) is [hashed](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/web_applications/web_app_helpers.cc;l=69;drc=cafa646efbb6f668d3ba20ff482c1f729159ae97) to be stored to [WebApp->app_id()](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/web_applications/web_app.h;l=43;drc=cafa646efbb6f668d3ba20ff482c1f729159ae97;bpv=1;bpt=1). +The `id` specified in manifest represents the identity of the web app. The manifest id is processed following the algorithm described in [appmanifest specification](https://www.w3.org/TR/appmanifest/#id-member) to produce the app's identity. In web app system, the app's [identity](https://www.w3.org/TR/appmanifest/#dfn-identity) is [hashed](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/web_applications/web_app_helpers.cc;l=69;drc=cafa646efbb6f668d3ba20ff482c1f729159ae97) to be stored to [WebApp->app_id()](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/web_applications/web_app.h;l=43;drc=cafa646efbb6f668d3ba20ff482c1f729159ae97;bpv=1;bpt=1). The app identity is verified in manifest updating process, if an app gets a manifest with [mismatched identity](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/web_applications/manifest_update_task.cc;l=315?q=manifest_update_task&ss=chromium%2Fchromium%2Fsrc), the update process is aborted. ### Scope @@ -200,7 +200,7 @@ This is for all installs that are not initiated by the user. This includes [preinstalled apps](preinstalled_web_app_manager.h), [policy installed apps](policy/web_app_policy_manager.h) and -[system web apps](system_web_apps/system_web_app_manager.h). +[system web apps](../ash/system_web_apps/system_web_app_manager.h). These all specify a set of [install URLs](external_install_options.h) which the `ExternallyManagedAppManager` synchronises the set of currently
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 aa4341c..6ac2579 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
@@ -81,8 +81,8 @@ #include "chrome/browser/ash/crostini/crostini_terminal.h" #include "chrome/browser/ash/file_manager/app_id.h" #include "chrome/browser/ash/login/demo_mode/demo_session.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/chromeos/arc/arc_web_contents_data.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "components/app_restore/app_launch_info.h" #include "components/app_restore/full_restore_save_handler.h" #include "components/app_restore/full_restore_utils.h" @@ -273,12 +273,13 @@ } #endif -WebAppPublisherHelper::WebAppPublisherHelper(Profile* profile, - WebAppProvider* provider, - SystemWebAppManager* swa_manager, - apps::AppType app_type, - Delegate* delegate, - bool observe_media_requests) +WebAppPublisherHelper::WebAppPublisherHelper( + Profile* profile, + WebAppProvider* provider, + ash::SystemWebAppManager* swa_manager, + apps::AppType app_type, + Delegate* delegate, + bool observe_media_requests) : profile_(profile), provider_(provider), swa_manager_(swa_manager),
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h index aeaaac4..8e1619c 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
@@ -63,6 +63,10 @@ class ContentSettingsTypeSet; class Profile; +namespace ash { +class SystemWebAppManager; +} + namespace apps { struct AppLaunchParams; } @@ -77,7 +81,6 @@ namespace web_app { -class SystemWebAppManager; class WebApp; class WebAppProvider; class WebAppLaunchManager; @@ -120,7 +123,7 @@ WebAppPublisherHelper(Profile* profile, WebAppProvider* provider, - SystemWebAppManager* swa_manager, + ash::SystemWebAppManager* swa_manager, apps::AppType app_type, Delegate* delegate, bool observe_media_requests); @@ -412,7 +415,7 @@ const raw_ptr<WebAppProvider> provider_; // nullptr for Lacros Chrome, valid pointer otherwise. - const raw_ptr<SystemWebAppManager> swa_manager_; + const raw_ptr<ash::SystemWebAppManager> swa_manager_; // The app type of the publisher. The app type is kSystemWeb if the web apps // are serving from Lacros, and the app type is kWeb for all other cases.
diff --git a/chrome/browser/web_applications/app_service/web_apps.cc b/chrome/browser/web_applications/app_service/web_apps.cc index b85713c..29ad9a1 100644 --- a/chrome/browser/web_applications/app_service/web_apps.cc +++ b/chrome/browser/web_applications/app_service/web_apps.cc
@@ -12,9 +12,9 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/intent_util.h" #include "chrome/browser/apps/app_service/launch_utils.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" @@ -93,12 +93,13 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) instance_registry_(&proxy->InstanceRegistry()), #endif - publisher_helper_(profile_, - provider_, - SystemWebAppManager::GetForLocalAppsUnchecked(profile_), - app_type_, - this, - ShouldObserveMediaRequests()) { + publisher_helper_( + profile_, + provider_, + ash::SystemWebAppManager::GetForLocalAppsUnchecked(profile_), + app_type_, + this, + ShouldObserveMediaRequests()) { Initialize(proxy->AppService()); } @@ -396,7 +397,7 @@ web_app->client_data().system_web_app_data->system_app_type; auto* system_app = - SystemWebAppManager::Get(profile())->GetSystemApp(swa_type); + ash::SystemWebAppManager::Get(profile())->GetSystemApp(swa_type); if (system_app && system_app->ShouldShowNewWindowMenuOption()) { apps::AddCommandItem(menu_type == apps::mojom::MenuType::kAppList ? ash::LAUNCH_NEW
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.cc index 80f1db4..fda6bb6 100644 --- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.cc +++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/browser_app_launcher.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" @@ -30,8 +31,8 @@ SystemWebAppBrowserTestBase::~SystemWebAppBrowserTestBase() = default; -SystemWebAppManager& SystemWebAppBrowserTestBase::GetManager() { - auto* swa_manager = SystemWebAppManager::Get(browser()->profile()); +ash::SystemWebAppManager& SystemWebAppBrowserTestBase::GetManager() { + auto* swa_manager = ash::SystemWebAppManager::Get(browser()->profile()); DCHECK(swa_manager); return *swa_manager; }
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h b/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h index e7e5e8b0..92d416e 100644 --- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h +++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_browsertest_base.h
@@ -27,6 +27,7 @@ namespace ash { enum class SystemWebAppType; +class SystemWebAppManager; } namespace web_app { @@ -47,7 +48,7 @@ // Returns the SystemWebAppManager for browser()->profile(). For incognito // profiles, this will be the SystemWebAppManager of the original profile. // Returns TestSystemWebAppManager if initialized with |install_mock| true. - SystemWebAppManager& GetManager(); + ash::SystemWebAppManager& GetManager(); // Returns ash::SystemWebAppType of mocked app, only valid if |install_mock| // is true.
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc index 8b0ce6d..25765e9f 100644 --- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
@@ -72,6 +72,7 @@ #include "chrome/browser/ash/accessibility/accessibility_manager.h" #include "chrome/browser/ash/accessibility/speech_monitor.h" #include "chrome/browser/ash/file_manager/file_manager_test_util.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/policy/system_features_disable_list_policy_handler.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" @@ -1129,7 +1130,7 @@ // resets the OnAppsSynchronized signal, and starts a new synchronize request. void WaitForSystemAppsSynchronized() { base::RunLoop run_loop; - SystemWebAppManager::Get(browser()->profile()) + ash::SystemWebAppManager::Get(browser()->profile()) ->on_apps_synchronized() .Post(FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); @@ -1559,7 +1560,7 @@ void WaitForSystemAppsBackgroundTasksStart() { base::RunLoop run_loop; - SystemWebAppManager::Get(browser()->profile()) + ash::SystemWebAppManager::Get(browser()->profile()) ->on_tasks_started() .Post(FROM_HERE, run_loop.QuitClosure());
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc index fcbaead68..bf24a0d 100644 --- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include <memory> #include <vector> @@ -99,7 +99,8 @@ class SystemWebAppWaiter { public: - explicit SystemWebAppWaiter(SystemWebAppManager* system_web_app_manager) { + explicit SystemWebAppWaiter( + ash::SystemWebAppManager* system_web_app_manager) { system_web_app_manager->ResetOnAppsSynchronizedForTesting(); system_web_app_manager->on_apps_synchronized().Post( FROM_HERE, base::BindLambdaForTesting([&]() { @@ -362,7 +363,7 @@ TEST_F(SystemWebAppManagerTest, AlwaysUpdate) { system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kAlwaysUpdate); + ash::SystemWebAppManager::UpdatePolicy::kAlwaysUpdate); InitEmptyRegistrar(); { @@ -407,7 +408,7 @@ externally_managed_app_manager().install_requests(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); InitEmptyRegistrar(); { @@ -498,7 +499,7 @@ externally_managed_app_manager().install_requests(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); InitEmptyRegistrar(); @@ -535,19 +536,19 @@ TEST_F(SystemWebAppManagerTest, InstallResultHistogram) { base::HistogramTester histograms; const std::string settings_app_install_result_histogram = - std::string(SystemWebAppManager::kInstallResultHistogramName) + ".Apps." + - kSettingsAppInternalName; + std::string(ash::SystemWebAppManager::kInstallResultHistogramName) + + ".Apps." + kSettingsAppInternalName; const std::string camera_app_install_result_histogram = - std::string(SystemWebAppManager::kInstallResultHistogramName) + ".Apps." + - kCameraAppInternalName; + std::string(ash::SystemWebAppManager::kInstallResultHistogramName) + + ".Apps." + kCameraAppInternalName; // Profile category for Chrome OS testing environment is "Other". const std::string profile_install_result_histogram = - std::string(SystemWebAppManager::kInstallResultHistogramName) + + std::string(ash::SystemWebAppManager::kInstallResultHistogramName) + ".Profiles.Other"; InitEmptyRegistrar(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kAlwaysUpdate); + ash::SystemWebAppManager::UpdatePolicy::kAlwaysUpdate); { ash::SystemWebAppDelegateMap system_apps; @@ -559,18 +560,18 @@ system_web_app_manager().SetSystemAppsForTesting(std::move(system_apps)); histograms.ExpectTotalCount( - SystemWebAppManager::kInstallResultHistogramName, 0); + ash::SystemWebAppManager::kInstallResultHistogramName, 0); histograms.ExpectTotalCount(settings_app_install_result_histogram, 0); histograms.ExpectTotalCount(profile_install_result_histogram, 0); histograms.ExpectTotalCount( - SystemWebAppManager::kInstallDurationHistogramName, 0); + ash::SystemWebAppManager::kInstallDurationHistogramName, 0); StartAndWaitForAppsToSynchronize(); histograms.ExpectTotalCount( - SystemWebAppManager::kInstallResultHistogramName, 1); + ash::SystemWebAppManager::kInstallResultHistogramName, 1); histograms.ExpectBucketCount( - SystemWebAppManager::kInstallResultHistogramName, + ash::SystemWebAppManager::kInstallResultHistogramName, webapps::InstallResultCode::kSuccessOfflineOnlyInstall, 1); histograms.ExpectTotalCount(settings_app_install_result_histogram, 1); histograms.ExpectBucketCount( @@ -581,7 +582,7 @@ profile_install_result_histogram, webapps::InstallResultCode::kSuccessOfflineOnlyInstall, 1); histograms.ExpectTotalCount( - SystemWebAppManager::kInstallDurationHistogramName, 1); + ash::SystemWebAppManager::kInstallDurationHistogramName, 1); } externally_managed_app_manager().SetHandleInstallRequestCallback( @@ -609,9 +610,9 @@ StartAndWaitForAppsToSynchronize(); histograms.ExpectTotalCount( - SystemWebAppManager::kInstallResultHistogramName, 3); + ash::SystemWebAppManager::kInstallResultHistogramName, 3); histograms.ExpectBucketCount( - SystemWebAppManager::kInstallResultHistogramName, + ash::SystemWebAppManager::kInstallResultHistogramName, webapps::InstallResultCode::kWebAppDisabled, 2); histograms.ExpectTotalCount(settings_app_install_result_histogram, 2); histograms.ExpectBucketCount(settings_app_install_result_histogram, @@ -632,7 +633,7 @@ system_web_app_manager().SetSystemAppsForTesting(std::move(system_apps)); histograms.ExpectTotalCount( - SystemWebAppManager::kInstallDurationHistogramName, 2); + ash::SystemWebAppManager::kInstallDurationHistogramName, 2); histograms.ExpectBucketCount( settings_app_install_result_histogram, webapps::InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 0); @@ -648,10 +649,10 @@ } histograms.ExpectBucketCount( - SystemWebAppManager::kInstallResultHistogramName, + ash::SystemWebAppManager::kInstallResultHistogramName, webapps::InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 1); histograms.ExpectBucketCount( - SystemWebAppManager::kInstallResultHistogramName, + ash::SystemWebAppManager::kInstallResultHistogramName, webapps::InstallResultCode::kWebAppDisabled, 2); histograms.ExpectBucketCount( @@ -662,7 +663,7 @@ webapps::InstallResultCode::kCancelledOnWebAppProviderShuttingDown, 1); // If install was interrupted by shutdown, do not report duration. histograms.ExpectTotalCount( - SystemWebAppManager::kInstallDurationHistogramName, 2); + ash::SystemWebAppManager::kInstallDurationHistogramName, 2); } } @@ -670,14 +671,14 @@ InstallResultHistogram_ExcludeAlreadyInstalled) { base::HistogramTester histograms; const std::string settings_app_install_result_histogram = - std::string(SystemWebAppManager::kInstallResultHistogramName) + ".Apps." + - kSettingsAppInternalName; + std::string(ash::SystemWebAppManager::kInstallResultHistogramName) + + ".Apps." + kSettingsAppInternalName; const std::string camera_app_install_result_histogram = - std::string(SystemWebAppManager::kInstallResultHistogramName) + ".Apps." + - kCameraAppInternalName; + std::string(ash::SystemWebAppManager::kInstallResultHistogramName) + + ".Apps." + kCameraAppInternalName; // Profile category for Chrome OS testing environment is "Other". const std::string profile_install_result_histogram = - std::string(SystemWebAppManager::kInstallResultHistogramName) + + std::string(ash::SystemWebAppManager::kInstallResultHistogramName) + ".Profiles.Other"; InitEmptyRegistrar(); @@ -707,8 +708,8 @@ StartAndWaitForAppsToSynchronize(); // Record results that aren't kSuccessAlreadyInstalled. - histograms.ExpectTotalCount(SystemWebAppManager::kInstallResultHistogramName, - 1); + histograms.ExpectTotalCount( + ash::SystemWebAppManager::kInstallResultHistogramName, 1); histograms.ExpectTotalCount(settings_app_install_result_histogram, 0); histograms.ExpectTotalCount(camera_app_install_result_histogram, 1); histograms.ExpectTotalCount(profile_install_result_histogram, 1); @@ -731,7 +732,7 @@ AppUrl2(), GetApp2WebAppInfoFactory())); system_web_app_manager().SetSystemAppsForTesting(std::move(system_apps)); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); { externally_managed_app_manager().SetHandleInstallRequestCallback( @@ -750,7 +751,7 @@ // The install duration histogram should be recorded, because the first // install happens on a clean profile. histograms.ExpectTotalCount( - SystemWebAppManager::kInstallDurationHistogramName, 1); + ash::SystemWebAppManager::kInstallDurationHistogramName, 1); } { @@ -769,7 +770,7 @@ // Don't record install duration histogram, because this time we don't ask // to force install all apps. histograms.ExpectTotalCount( - SystemWebAppManager::kInstallDurationHistogramName, 1); + ash::SystemWebAppManager::kInstallDurationHistogramName, 1); } } @@ -778,7 +779,7 @@ externally_managed_app_manager().install_requests(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); InitEmptyRegistrar(); @@ -851,7 +852,7 @@ externally_managed_app_manager().install_requests(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); InitEmptyRegistrar(); @@ -922,7 +923,7 @@ externally_managed_app_manager().install_requests(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); InitEmptyRegistrar(); @@ -997,7 +998,7 @@ InitEmptyRegistrar(); system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); // Register a test system app. ash::SystemWebAppDelegateMap system_apps; @@ -1033,7 +1034,7 @@ TEST_F(SystemWebAppManagerTest, IsSWABeforeSync) { system_web_app_manager().SetUpdatePolicy( - SystemWebAppManager::UpdatePolicy::kOnVersionChange); + ash::SystemWebAppManager::UpdatePolicy::kOnVersionChange); InitEmptyRegistrar();
diff --git a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc index 5a40e46..7829331 100644 --- a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc +++ b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc
@@ -13,7 +13,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "chrome/browser/apps/app_service/app_launch_params.h" -#include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h" @@ -781,7 +780,8 @@ } auto provider = std::make_unique<FakeWebAppProvider>(profile); - auto system_web_app_manager = std::make_unique<SystemWebAppManager>(profile); + auto system_web_app_manager = + std::make_unique<ash::SystemWebAppManager>(profile); system_web_app_manager->SetSystemAppsForTesting( std::move(system_app_delegates_)); @@ -802,7 +802,8 @@ Profile* profile) { profile_ = profile; auto provider = std::make_unique<FakeWebAppProvider>(profile); - auto system_web_app_manager = std::make_unique<SystemWebAppManager>(profile); + auto system_web_app_manager = + std::make_unique<ash::SystemWebAppManager>(profile); system_web_app_manager->SetSystemAppsForTesting({}); system_web_app_manager->SetUpdatePolicyForTesting(update_policy_); provider->SetSystemWebAppManager(std::move(system_web_app_manager)); @@ -812,7 +813,7 @@ void TestSystemWebAppInstallation::WaitForAppInstall() { base::RunLoop run_loop; - SystemWebAppManager::GetForTest(profile_)->on_apps_synchronized().Post( + ash::SystemWebAppManager::GetForTest(profile_)->on_apps_synchronized().Post( FROM_HERE, base::BindLambdaForTesting([&]() { // Wait one execution loop for on_apps_synchronized() to be // called on all listeners. @@ -823,7 +824,7 @@ } AppId TestSystemWebAppInstallation::GetAppId() { - return SystemWebAppManager::GetForTest(profile_) + return ash::SystemWebAppManager::GetForTest(profile_) ->GetAppIdForSystemApp(type_.value()) .value(); }
diff --git a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h index 0ada174..8cb7980b8 100644 --- a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h +++ b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h
@@ -8,8 +8,8 @@ #include <memory> #include "base/memory/raw_ptr.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_web_ui_controller_factory.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" #include "chrome/browser/web_applications/web_app_install_info.h" @@ -223,7 +223,7 @@ ash::SystemWebAppDelegate* GetDelegate(); ash::SystemWebAppType GetType(); - void set_update_policy(SystemWebAppManager::UpdatePolicy update_policy) { + void set_update_policy(ash::SystemWebAppManager::UpdatePolicy update_policy) { update_policy_ = update_policy; } @@ -242,8 +242,8 @@ void RegisterAutoGrantedPermissions(ContentSettingsType permission); raw_ptr<Profile> profile_; - SystemWebAppManager::UpdatePolicy update_policy_ = - SystemWebAppManager::UpdatePolicy::kAlwaysUpdate; + ash::SystemWebAppManager::UpdatePolicy update_policy_ = + ash::SystemWebAppManager::UpdatePolicy::kAlwaysUpdate; std::unique_ptr<FakeWebAppProviderCreator> fake_web_app_provider_creator_; // nullopt if SetUpWithoutApps() was used. const absl::optional<ash::SystemWebAppType> type_;
diff --git a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h index 8935b81..262912e 100644 --- a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h +++ b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h
@@ -9,14 +9,14 @@ #include <vector> #include "base/version.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "url/gurl.h" class Profile; namespace web_app { -class TestSystemWebAppManager : public SystemWebAppManager { +class TestSystemWebAppManager : public ash::SystemWebAppManager { public: explicit TestSystemWebAppManager(Profile* profile); TestSystemWebAppManager(const TestSystemWebAppManager&) = delete; @@ -33,7 +33,7 @@ current_locale_ = locale; } - // SystemWebAppManager: + // ash::SystemWebAppManager: const base::Version& CurrentVersion() const override; const std::string& CurrentLocale() const override;
diff --git a/chrome/browser/web_applications/test/fake_web_app_provider.cc b/chrome/browser/web_applications/test/fake_web_app_provider.cc index 678f6f2..141d603 100644 --- a/chrome/browser/web_applications/test/fake_web_app_provider.cc +++ b/chrome/browser/web_applications/test/fake_web_app_provider.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/web_applications/externally_managed_app_manager.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h" #include "chrome/browser/web_applications/test/fake_externally_managed_app_manager.h" #include "chrome/browser/web_applications/test/fake_os_integration_manager.h" @@ -144,7 +143,7 @@ } void FakeWebAppProvider::SetSystemWebAppManager( - std::unique_ptr<SystemWebAppManager> system_web_app_manager) { + std::unique_ptr<ash::SystemWebAppManager> system_web_app_manager) { CheckNotStarted(); system_web_app_manager_ = std::move(system_web_app_manager); }
diff --git a/chrome/browser/web_applications/test/fake_web_app_provider.h b/chrome/browser/web_applications/test/fake_web_app_provider.h index d57ad74..bb92d16 100644 --- a/chrome/browser/web_applications/test/fake_web_app_provider.h +++ b/chrome/browser/web_applications/test/fake_web_app_provider.h
@@ -17,6 +17,10 @@ class KeyedService; class Profile; +namespace ash { +class SystemWebAppManager; +} + namespace content { class BrowserContext; } @@ -28,7 +32,6 @@ class OsIntegrationManager; class WebAppInstallFinalizer; class ExternallyManagedAppManager; -class SystemWebAppManager; class WebAppInstallManager; class WebAppPolicyManager; class WebAppIconManager; @@ -81,7 +84,7 @@ externally_managed_app_manager); void SetWebAppUiManager(std::unique_ptr<WebAppUiManager> ui_manager); void SetSystemWebAppManager( - std::unique_ptr<SystemWebAppManager> system_web_app_manager); + std::unique_ptr<ash::SystemWebAppManager> system_web_app_manager); void SetWebAppPolicyManager( std::unique_ptr<WebAppPolicyManager> web_app_policy_manager); void SetCommandManager(std::unique_ptr<WebAppCommandManager> command_manager);
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h index 8ac601c7..0c25bdb 100644 --- a/chrome/browser/web_applications/web_app_constants.h +++ b/chrome/browser/web_applications/web_app_constants.h
@@ -130,7 +130,7 @@ // Installed as a Chrome component, such as a help app, or a settings app. // The corresponding ExternallyManagedAppManager::SynchronizeInstalledApps // call site is - // in SystemWebAppManager::RefreshPolicyInstalledApps. + // in ash::SystemWebAppManager::RefreshPolicyInstalledApps. kSystemInstalled = 3, // Installed from ARC.
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc index 4b34602..6d31f64 100644 --- a/chrome/browser/web_applications/web_app_database.cc +++ b/chrome/browser/web_applications/web_app_database.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/ash/system_web_apps/types/system_web_app_type.h" #include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h" #include "chrome/browser/web_applications/proto/web_app.pb.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/user_display_mode.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_chromeos_data.h"
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index d547779..acae65ff 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/daily_metrics_helper.h" #include "chrome/browser/web_applications/externally_installed_web_app_prefs.h" @@ -29,7 +30,6 @@ #include "chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/preinstalled_web_app_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.h" #include "chrome/browser/web_applications/web_app_audio_focus_id_map.h" #include "chrome/browser/web_applications/web_app_command_manager.h" @@ -237,7 +237,7 @@ std::make_unique<ExternallyManagedAppManagerImpl>(profile); preinstalled_web_app_manager_ = std::make_unique<PreinstalledWebAppManager>(profile); - system_web_app_manager_ = std::make_unique<SystemWebAppManager>(profile); + system_web_app_manager_ = std::make_unique<ash::SystemWebAppManager>(profile); web_app_policy_manager_ = std::make_unique<WebAppPolicyManager>(profile); database_factory_ = std::make_unique<WebAppDatabaseFactory>(profile); @@ -372,7 +372,7 @@ ExternallyInstalledWebAppPrefs::RegisterProfilePrefs(registry); PreinstalledWebAppManager::RegisterProfilePrefs(registry); WebAppPolicyManager::RegisterProfilePrefs(registry); - SystemWebAppManager::RegisterProfilePrefs(registry); + ash::SystemWebAppManager::RegisterProfilePrefs(registry); WebAppPrefsUtilsRegisterProfilePrefs(registry); IsolationPrefsUtilsRegisterProfilePrefs(registry); RegisterInstallBounceMetricProfilePrefs(registry);
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h index a0ac8ad..576ec7b8 100644 --- a/chrome/browser/web_applications/web_app_provider.h +++ b/chrome/browser/web_applications/web_app_provider.h
@@ -18,6 +18,10 @@ class Profile; +namespace ash { +class SystemWebAppManager; +} + namespace content { class WebContents; } @@ -34,7 +38,6 @@ class PreinstalledWebAppManager; class WebAppInstallFinalizer; class ManifestUpdateManager; -class SystemWebAppManager; class WebAppAudioFocusIdMap; class WebAppInstallManager; class WebAppPolicyManager; @@ -146,7 +149,7 @@ protected: // TODO(crbug.com/1321984): Delete system_web_app_manager_. - friend class SystemWebAppManager; + friend class ash::SystemWebAppManager; virtual void StartImpl(); @@ -177,7 +180,7 @@ std::unique_ptr<ExternallyManagedAppManager> externally_managed_app_manager_; // TODO(crbug.com/1321984): Extract system web app manager as // chrome/browser/ash/ keyed service. - std::unique_ptr<SystemWebAppManager> system_web_app_manager_; + std::unique_ptr<ash::SystemWebAppManager> system_web_app_manager_; std::unique_ptr<WebAppAudioFocusIdMap> audio_focus_id_map_; std::unique_ptr<WebAppInstallManager> install_manager_; std::unique_ptr<WebAppPolicyManager> web_app_policy_manager_;
diff --git a/chrome/browser/web_applications/web_app_tab_helper.cc b/chrome/browser/web_applications/web_app_tab_helper.cc index 8c1a5a0..1d86f77 100644 --- a/chrome/browser/web_applications/web_app_tab_helper.cc +++ b/chrome/browser/web_applications/web_app_tab_helper.cc
@@ -8,11 +8,11 @@ #include <string> #include "base/unguessable_token.h" +#include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/manifest_update_manager.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app_audio_focus_id_map.h" #include "chrome/browser/web_applications/web_app_launch_queue.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -82,11 +82,12 @@ } // If navigating to a System Web App (including navigation in sub frames), let - // SystemWebAppManager perform tab-secific setup for navigations in System Web - // Apps. + // ash::SystemWebAppManager perform tab-secific setup for navigations in + // System Web Apps. Profile* profile = Profile::FromBrowserContext(web_contents()->GetBrowserContext()); - auto* swa_manager = SystemWebAppManager::GetForLocalAppsUnchecked(profile); + auto* swa_manager = + ash::SystemWebAppManager::GetForLocalAppsUnchecked(profile); if (swa_manager && swa_manager->IsSystemWebApp(GetAppId())) { swa_manager->OnReadyToCommitNavigation(GetAppId(), navigation_handle); }
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 52fd2d1..f785c06 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1653868687-f3ebdb1b5e447a8e6345d2def98cadf518c38c24.profdata +chrome-linux-main-1653911525-bc6c69dfadd05727f8ff3f0b2a8a30a216286070.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 7761f669..74c06ad 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1653738865-a6004ac5e9ac4b2e6f275d60209e3871ee91c367.profdata +chrome-mac-arm-main-1653911525-52b18476e3e1cda3d2599275ca075f6156d6cbd3.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 5e1646c..9da2c82 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1653845817-e60dcd3c8bd0bdebd9eeaf9fe5ff6b3c08892673.profdata +chrome-mac-main-1653911525-d54dc8c3a4f079ff8e9ffdf8620f6b6cb9b4e444.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 7e26221..73b2b14 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1653857657-444d1af0b053e96627578576f24bec7777612f86.profdata +chrome-win32-main-1653901050-ea64c0f1f97a6110406d1df594f687a0365d7ed8.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 403b3b2..1f633e51 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1653857657-fb61dce926405d7dddd23cf6bfd788a0aeba7efc.profdata +chrome-win64-main-1653901050-13b3905958cb87d734e06845c5d6ce3b69a51661.profdata
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index eef910ed..48b2fa0 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -133,6 +133,10 @@ const char kCreateBrowserOnStartupForTests[] = "create-browser-on-startup-for-tests"; +// Prints licensing information (same content as found in about:credits) and +// quits. +const char kCredits[] = "credits"; + // Specifies the http:// endpoint which will be used to serve // devtools://devtools/custom/<path> // Or a file:// URL to specify a custom file path to load from for
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 4d44628..364619f 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -59,6 +59,7 @@ extern const char kCipherSuiteBlacklist[]; extern const char kCrashOnHangThreads[]; extern const char kCreateBrowserOnStartupForTests[]; +extern const char kCredits[]; extern const char kCustomDevtoolsFrontend[]; extern const char kDebugEnableFrameToggle[]; extern const char kDebugPackedApps[];
diff --git a/chrome/common/extensions/api/terminal_private.json b/chrome/common/extensions/api/terminal_private.json index 2943a3c..316a04c 100644 --- a/chrome/common/extensions/api/terminal_private.json +++ b/chrome/common/extensions/api/terminal_private.json
@@ -237,12 +237,16 @@ { "name": "info", "type": "object", - "properties": { - "tmux_integration": { + "properties": { + "multi_profile": { + "description": "True if multi profile settings is enabled.", + "type": "boolean" + }, + "tmux_integration": { "description": "True if tmux control mode integration is enabled.", "type": "boolean" } - }, + }, "description": "Information about which features are enabled." } ]
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 6507421..f8e4a1a 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -3999,7 +3999,7 @@ CheckTextFieldsSuggestedState("", false, kAlicePassword, true); password_autofill_agent_->OnDynamicFormsSeen(); - CheckTextFieldsSuggestedState(kAliceUsername, false, kAlicePassword, true); + CheckTextFieldsSuggestedState(kAliceUsername, true, kAlicePassword, true); EXPECT_FALSE(fake_driver_.called_password_forms_parsed()); EXPECT_FALSE(fake_driver_.called_password_forms_rendered());
diff --git a/chrome/services/speech/speech_recognition_service_impl.cc b/chrome/services/speech/speech_recognition_service_impl.cc index ba20291..9a81b71f 100644 --- a/chrome/services/speech/speech_recognition_service_impl.cc +++ b/chrome/services/speech/speech_recognition_service_impl.cc
@@ -21,7 +21,13 @@ SpeechRecognitionServiceImpl::~SpeechRecognitionServiceImpl() = default; -void SpeechRecognitionServiceImpl::BindContext( +void SpeechRecognitionServiceImpl::BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + context) { + audio_source_speech_recognition_contexts_.Add(this, std::move(context)); +} + +void SpeechRecognitionServiceImpl::BindSpeechRecognitionContext( mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> context) { speech_recognition_contexts_.Add(this, std::move(context)); }
diff --git a/chrome/services/speech/speech_recognition_service_impl.h b/chrome/services/speech/speech_recognition_service_impl.h index a3074d7..79bf750d 100644 --- a/chrome/services/speech/speech_recognition_service_impl.h +++ b/chrome/services/speech/speech_recognition_service_impl.h
@@ -18,6 +18,7 @@ // recognition. class SpeechRecognitionServiceImpl : public media::mojom::SpeechRecognitionService, + public media::mojom::AudioSourceSpeechRecognitionContext, public media::mojom::SpeechRecognitionContext { public: explicit SpeechRecognitionServiceImpl( @@ -29,32 +30,40 @@ ~SpeechRecognitionServiceImpl() override; - // media::mojom::SpeechRecognitionService - void BindContext(mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> - context) override; + // media::mojom::SpeechRecognitionService: + void BindSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::SpeechRecognitionContext> context) + override; + void BindAudioSourceSpeechRecognitionContext( + mojo::PendingReceiver<media::mojom::AudioSourceSpeechRecognitionContext> + context) override; void SetSodaPath(const base::FilePath& binary_path, const base::FilePath& config_path) override; - // media::mojom::SpeechRecognitionContext + // media::mojom::SpeechRecognitionContext: void BindRecognizer( mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizer> receiver, mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> client, media::mojom::SpeechRecognitionOptionsPtr options, BindRecognizerCallback callback) override; + + // media::mojom::AudioSourceSpeechRecognitionContext: void BindAudioSourceFetcher( mojo::PendingReceiver<media::mojom::AudioSourceFetcher> fetcher_receiver, mojo::PendingRemote<media::mojom::SpeechRecognitionRecognizerClient> client, media::mojom::SpeechRecognitionOptionsPtr options, - BindRecognizerCallback callback) override; + BindAudioSourceFetcherCallback callback) override; protected: mojo::Receiver<media::mojom::SpeechRecognitionService> receiver_; - // The set of receivers used to receive messages from the renderer clients. + // The sets of receivers used to receive messages from the clients. mojo::ReceiverSet<media::mojom::SpeechRecognitionContext> speech_recognition_contexts_; + mojo::ReceiverSet<media::mojom::AudioSourceSpeechRecognitionContext> + audio_source_speech_recognition_contexts_; base::FilePath binary_path_ = base::FilePath(); base::FilePath config_path_ = base::FilePath();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b0cae0c1..847d33c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1173,6 +1173,7 @@ "//chrome/browser:theme_properties", "//chrome/browser/accessibility:test_support", "//chrome/browser/apps/app_service:test_support", + "//chrome/browser/ash/system_web_apps/types:types", "//chrome/browser/breadcrumbs:browser_tests", "//chrome/browser/browsing_data:constants", "//chrome/browser/continuous_search:browser_tests", @@ -9599,6 +9600,8 @@ "../browser/sync/test/integration/exponential_backoff_helper.h", "../browser/sync/test/integration/fake_server_invalidation_sender.cc", "../browser/sync/test/integration/fake_server_invalidation_sender.h", + "../browser/sync/test/integration/fake_server_match_status_checker.cc", + "../browser/sync/test/integration/fake_server_match_status_checker.h", "../browser/sync/test/integration/fake_server_sync_invalidation_sender.cc", "../browser/sync/test/integration/fake_server_sync_invalidation_sender.h", "../browser/sync/test/integration/multi_client_status_change_checker.cc", @@ -9650,8 +9653,6 @@ "../browser/sync/test/integration/extension_settings_helper.h", "../browser/sync/test/integration/extensions_helper.cc", "../browser/sync/test/integration/extensions_helper.h", - "../browser/sync/test/integration/fake_server_match_status_checker.cc", - "../browser/sync/test/integration/fake_server_match_status_checker.h", "../browser/sync/test/integration/migration_waiter.cc", "../browser/sync/test/integration/migration_waiter.h", "../browser/sync/test/integration/migration_watcher.cc",
diff --git a/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_extension_test.js b/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_extension_test.js index fc88dab0..05f54f7f 100644 --- a/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_extension_test.js +++ b/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_extension_test.js
@@ -22,6 +22,13 @@ let emojiPicker; /** @type {function(...!string): ?HTMLElement} */ let findInEmojiPicker; + /** @type {function(...!string): ?HTMLElement} */ + let findEmojiFirstButton; + /** @type {string} */ + const emoticonGroupSelector = 'emoji-group[category="emoticon"]'; + /** @type {string} */ + const emoticonHistoryGroupSelector = + '[data-group="emoticon-history"] > emoji-group[category="emoticon"]'; setup(() => { // Reset DOM state. @@ -35,6 +42,14 @@ findInEmojiPicker = (...path) => deepQuerySelector(emojiPicker, path); + findEmojiFirstButton = (...path) => { + const emojiElement = deepQuerySelector(emojiPicker, path); + if (emojiElement) { + return emojiElement.firstEmojiButton(); + } + return null; + }; + // Wait until emoji data is loaded before executing tests. return new Promise((resolve) => { emojiPicker.addEventListener(V2_CONTENT_LOADED, () => { @@ -100,7 +115,8 @@ test('all emoticon groups should be rendered.', () => { assertEquals( emojiPicker.emoticonData.length, - emojiPicker.shadowRoot.querySelectorAll('emoticon-group').length); + emojiPicker.shadowRoot.querySelectorAll( + emoticonGroupSelector).length); }); test( @@ -108,7 +124,7 @@ 'number of emoticon entries.', async () => { const allEmoticonGroups = - emojiPicker.shadowRoot.querySelectorAll('emoticon-group'); + emojiPicker.shadowRoot.querySelectorAll(emoticonGroupSelector); for (let idx = 0; idx < allEmoticonGroups.length; ++idx) { const group = allEmoticonGroups[idx]; const actualFirstGroupName = @@ -120,7 +136,7 @@ emojiPicker.emoticonData[idx].emoji.length; await waitForCondition( () => expectedNumberOfEmoticons === - group.shadowRoot.querySelectorAll('.emoticon-button').length); + group.shadowRoot.querySelectorAll('emoji-button').length); } }); @@ -129,7 +145,7 @@ 'correct emoticon string and name.', async () => { const firstEmoticonButton = await waitForCondition( - () => findInEmojiPicker('emoticon-group', '.emoticon-button')); + () => findEmojiFirstButton(emoticonGroupSelector)); const expectedEmoticonString = emojiPicker.emoticonData[0].emoji[0].base.string; const expectedEmoticonName = @@ -172,23 +188,16 @@ EmojiPickerApiProxyImpl.getInstance().isIncognitoTextField = () => new Promise((resolve) => resolve({incognito: false})); - const emoticonButton = findInEmojiPicker('emoticon-group', 'button'); + const emoticonButton = findEmojiFirstButton(emoticonGroupSelector); emoticonButton.click(); - const recentEmoticonGroup = await waitForCondition( - () => findInEmojiPicker( - '[data-group=emoticon-history] emoticon-group')); - - const recentlyUsedEmoticonButton = - deepQuerySelector(recentEmoticonGroup, ['.emoticon-button']); + const recentlyUsedEmoticonButton = await waitForCondition( + () => findEmojiFirstButton(emoticonHistoryGroupSelector)); const buttonClickPromise = new Promise( (resolve) => emojiPicker.addEventListener(EMOJI_BUTTON_CLICK, (event) => { assertEquals( emoticonButton.innerHTML.trim(), event.detail.text); - assertEquals( - emoticonButton.getAttribute('emoticon-name'), - event.detail.name); resolve(); })); @@ -206,16 +215,16 @@ EmojiPickerApiProxyImpl.getInstance().isIncognitoTextField = () => new Promise((resolve) => resolve({incognito: false})); - const emoticonButton = findInEmojiPicker('emoticon-group', 'button'); + const emoticonButton = findEmojiFirstButton(emoticonGroupSelector); emoticonButton.click(); - const recentEmoticonGroup = await waitForCondition( - () => findInEmojiPicker( - '[data-group=emoticon-history] emoticon-group')); - assert(recentEmoticonGroup); + const recentEmoticonButton = await waitForCondition( + () => findEmojiFirstButton(emoticonHistoryGroupSelector)); + assert(recentEmoticonButton); const recentlyUsedEmoticons = - recentEmoticonGroup.shadowRoot.querySelectorAll('.emoticon-button'); + findInEmojiPicker(emoticonHistoryGroupSelector + ).shadowRoot.querySelectorAll('emoji-button'); assertEquals(1, recentlyUsedEmoticons.length); });
diff --git a/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_search_test.js b/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_search_test.js index f0e04cc..c715e5fc 100644 --- a/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_search_test.js +++ b/chrome/test/data/webui/chromeos/emoji_picker/emoji_picker_search_test.js
@@ -62,8 +62,9 @@ .shadowRoot.querySelectorAll('emoji-button'); assertGT(emojiResults.length, 0); const emoticonResults = - findInEmojiPicker('emoji-search', 'emoticon-group') - .shadowRoot.querySelectorAll('.emoticon-button'); + findInEmojiPicker( + 'emoji-search', 'emoji-group[category="emoticon"]') + .shadowRoot.querySelectorAll('emoji-button'); assertGT(emoticonResults.length, 0); });
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 9a5788a..8867f81 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -187,7 +187,7 @@ if (enable_cros_libassistant) { deps += [ - "//chromeos/services/assistant/audio_decoder:lib", + "//chromeos/ash/services/assistant/audio_decoder:lib", "//chromeos/services/assistant/public/mojom", "//chromeos/services/libassistant", "//chromeos/services/libassistant/public/mojom",
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index 7608256..d3400042 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -29,6 +29,7 @@ "+chrome/services/util_win/processor_metrics.h", "+chrome/services/util_win/public/mojom", "+chromeos/ash/components/assistant/buildflags.h", + "+chromeos/ash/services/assistant/audio_decoder", "+chromeos/components/local_search_service/local_search_service.h", "+chromeos/components/local_search_service/public/mojom", "+chromeos/components/quick_answers/public",
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc index 4450f88..64731cd 100644 --- a/chrome/utility/services.cc +++ b/chrome/utility/services.cc
@@ -121,7 +121,7 @@ #include "chromeos/services/tts/tts_service.h" #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) -#include "chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.h" // nogncheck +#include "chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.h" // nogncheck #include "chromeos/services/libassistant/libassistant_service.h" // nogncheck #endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT) #endif // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc b/chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc index 508aebc..6ba7ac0a 100644 --- a/chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc +++ b/chromeos/ash/components/network/onc/onc_translator_onc_to_shill.cc
@@ -297,7 +297,7 @@ onc_object_->FindStringKey(::onc::l2tp::kPassword); if (password && *password == ::onc::substitutes::kPasswordPlaceholderVerbatim) { - // TODO(b/147658302): shill::kL2TPIPsecUseLoginPasswordProperty is a string + // TODO(b/220249018): shill::kL2tpIpsecUseLoginPasswordProperty is a string // property containing "false" or "true". Migrate it to a bool to match // shill::kEapUseLoginPasswordProperty. shill_dictionary_->SetKey(shill::kL2TPIPsecUseLoginPasswordProperty,
diff --git a/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc index 6d943ed..692e8aa 100644 --- a/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc +++ b/chromeos/ash/components/network/onc/onc_translator_shill_to_onc.cc
@@ -363,7 +363,7 @@ std::move(lcp_echo_disabled_value)); } - // TODO(b/147658302): shill::kL2TPIPsecUseLoginPasswordProperty is a string + // TODO(b/220249018): shill::kL2tpIpsecUseLoginPasswordProperty is a string // property containing "false" or "true". Migrate it to a bool to match // shill::kEapUseLoginPasswordProperty. const std::string* use_login_password = shill_dictionary_->FindStringKey(
diff --git a/chromeos/ash/services/assistant/DEPS b/chromeos/ash/services/assistant/DEPS new file mode 100644 index 0000000..a9b9ba5b2 --- /dev/null +++ b/chromeos/ash/services/assistant/DEPS
@@ -0,0 +1,24 @@ +# TODO(https://crbug.com/1164001): When this file is edited, same file in +# //chromeos/services/assistant should be updated as well. We need to sync +# both files until the migration is done. + +include_rules = [ + "+ash/components/audio", + "+ash/public", + "+chromeos/ash/components/assistant", + "+chromeos/grit/chromeos_strings.h", + "+components/signin", + "+google_apis/gaia", + "+libassistant", + "+media/base", + "+media/mojo/mojom", + "+mojo/public", + "+services/audio/public", + "+services/device/public", + "+services/media_session/public", + "+services/network/public", + "+ui/accessibility/accessibility_switches.h", + "+ui/accessibility/ax_assistant_structure.h", + "+ui/accessibility/mojom", + "+ui/base", +]
diff --git a/chromeos/ash/services/assistant/DIR_METADATA b/chromeos/ash/services/assistant/DIR_METADATA new file mode 100644 index 0000000..5ba0efa --- /dev/null +++ b/chromeos/ash/services/assistant/DIR_METADATA
@@ -0,0 +1 @@ +mixins: "//chromeos/ash/components/assistant/COMMON_METADATA"
diff --git a/chromeos/ash/services/assistant/OWNERS b/chromeos/ash/services/assistant/OWNERS new file mode 100644 index 0000000..574ed11 --- /dev/null +++ b/chromeos/ash/services/assistant/OWNERS
@@ -0,0 +1 @@ +file://chromeos/ash/components/assistant/OWNERS
diff --git a/chromeos/services/assistant/audio_decoder/BUILD.gn b/chromeos/ash/services/assistant/audio_decoder/BUILD.gn similarity index 83% rename from chromeos/services/assistant/audio_decoder/BUILD.gn rename to chromeos/ash/services/assistant/audio_decoder/BUILD.gn index adfd4462..71e78eb 100644 --- a/chromeos/services/assistant/audio_decoder/BUILD.gn +++ b/chromeos/ash/services/assistant/audio_decoder/BUILD.gn
@@ -2,8 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//chromeos/ash/components/assistant/assistant.gni") +assert(is_chromeos_ash, "Non Chrome OS builds cannot depend on //chromeos/ash") assert(enable_cros_libassistant) source_set("lib") {
diff --git a/chromeos/services/assistant/audio_decoder/DEPS b/chromeos/ash/services/assistant/audio_decoder/DEPS similarity index 100% rename from chromeos/services/assistant/audio_decoder/DEPS rename to chromeos/ash/services/assistant/audio_decoder/DEPS
diff --git a/chromeos/services/assistant/audio_decoder/README.md b/chromeos/ash/services/assistant/audio_decoder/README.md similarity index 100% rename from chromeos/services/assistant/audio_decoder/README.md rename to chromeos/ash/services/assistant/audio_decoder/README.md
diff --git a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder.cc b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.cc similarity index 96% rename from chromeos/services/assistant/audio_decoder/assistant_audio_decoder.cc rename to chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.cc index 960147a1..da2ce071c 100644 --- a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder.cc +++ b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/assistant/audio_decoder/assistant_audio_decoder.h" +#include "chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.h" #include <utility> #include <vector> #include "base/bind.h" #include "base/threading/thread.h" -#include "chromeos/services/assistant/audio_decoder/ipc_data_source.h" +#include "chromeos/ash/services/assistant/audio_decoder/ipc_data_source.h" #include "media/base/audio_bus.h" #include "media/base/data_source.h" #include "media/filters/audio_file_reader.h"
diff --git a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder.h b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.h similarity index 91% rename from chromeos/services/assistant/audio_decoder/assistant_audio_decoder.h rename to chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.h index b16533c..f0f35641 100644 --- a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder.h +++ b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_H_ -#define CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_H_ +#ifndef CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_H_ +#define CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_H_ #include <memory> @@ -82,4 +82,4 @@ } // namespace assistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_H_ +#endif // CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_H_
diff --git a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.cc b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.cc similarity index 85% rename from chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.cc rename to chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.cc index 0ef1a9b..aba49f10 100644 --- a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.cc +++ b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.h" +#include "chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.h" -#include "chromeos/services/assistant/audio_decoder/assistant_audio_decoder.h" +#include "chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" namespace chromeos {
diff --git a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.h b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.h similarity index 82% rename from chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.h rename to chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.h index bb77b796..a7ca5a3 100644 --- a/chromeos/services/assistant/audio_decoder/assistant_audio_decoder_factory.h +++ b/chromeos/ash/services/assistant/audio_decoder/assistant_audio_decoder_factory.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_FACTORY_H_ -#define CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_FACTORY_H_ +#ifndef CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_FACTORY_H_ +#define CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_FACTORY_H_ #include "chromeos/services/assistant/public/mojom/assistant_audio_decoder.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -39,4 +39,4 @@ } // namespace assistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_FACTORY_H_ +#endif // CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_ASSISTANT_AUDIO_DECODER_FACTORY_H_
diff --git a/chromeos/services/assistant/audio_decoder/ipc_data_source.cc b/chromeos/ash/services/assistant/audio_decoder/ipc_data_source.cc similarity index 97% rename from chromeos/services/assistant/audio_decoder/ipc_data_source.cc rename to chromeos/ash/services/assistant/audio_decoder/ipc_data_source.cc index acde137..6a7ccb2 100644 --- a/chromeos/services/assistant/audio_decoder/ipc_data_source.cc +++ b/chromeos/ash/services/assistant/audio_decoder/ipc_data_source.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/assistant/audio_decoder/ipc_data_source.h" +#include "chromeos/ash/services/assistant/audio_decoder/ipc_data_source.h" #include <algorithm> #include <utility>
diff --git a/chromeos/services/assistant/audio_decoder/ipc_data_source.h b/chromeos/ash/services/assistant/audio_decoder/ipc_data_source.h similarity index 90% rename from chromeos/services/assistant/audio_decoder/ipc_data_source.h rename to chromeos/ash/services/assistant/audio_decoder/ipc_data_source.h index 82667a4..1d043d92 100644 --- a/chromeos/services/assistant/audio_decoder/ipc_data_source.h +++ b/chromeos/ash/services/assistant/audio_decoder/ipc_data_source.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_IPC_DATA_SOURCE_H_ -#define CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_IPC_DATA_SOURCE_H_ +#ifndef CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_IPC_DATA_SOURCE_H_ +#define CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_IPC_DATA_SOURCE_H_ #include <stdint.h> @@ -63,4 +63,4 @@ } // namespace assistant } // namespace chromeos -#endif // CHROMEOS_SERVICES_ASSISTANT_AUDIO_DECODER_IPC_DATA_SOURCE_H_ +#endif // CHROMEOS_ASH_SERVICES_ASSISTANT_AUDIO_DECODER_IPC_DATA_SOURCE_H_
diff --git a/chromeos/crosapi/mojom/device_settings_service.mojom b/chromeos/crosapi/mojom/device_settings_service.mojom index 8bcd0706..21fbacd5 100644 --- a/chromeos/crosapi/mojom/device_settings_service.mojom +++ b/chromeos/crosapi/mojom/device_settings_service.mojom
@@ -35,6 +35,9 @@ // The value of UsbDetachableAllowlist device policy. UsbDetachableAllowlist? usb_detachable_allow_list@2; + // The value of DeviceEphemeralUsersEnabled device policy. + [MinVersion=1] OptionalBool device_ephemeral_users_enabled@3; + [Stable] enum OptionalBool { kUnset,
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 70f1cd9..42b527a 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -28,6 +28,7 @@ #include "chromeos/dbus/shill/shill_manager_client.h" #include "chromeos/dbus/shill/shill_profile_client.h" #include "chromeos/dbus/shill/shill_service_client.h" +#include "chromeos/network/cellular_policy_handler.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_device_handler.h" @@ -560,8 +561,7 @@ auto policy_applicator = std::make_unique<PolicyApplicator>( *profile, policies->GetGuidToPolicyMap(), policies->GetGlobalNetworkConfig()->Clone(), this, - cellular_policy_handler_, managed_cellular_pref_handler_, - modified_policies); + managed_cellular_pref_handler_, modified_policies); auto* policy_applicator_unowned = policy_applicator.get(); policy_applicators_[userhash] = std::move(policy_applicator); policy_applicator_unowned->Run(); @@ -638,19 +638,63 @@ std::move(split_callback.second), FROM_HERE)); } +void ManagedNetworkConfigurationHandlerImpl::TriggerCellularPolicyApplication( + const NetworkProfile& profile, + const base::flat_set<std::string>& new_cellular_policy_guids) { + const ProfilePolicies* policies = GetPoliciesForUser(profile.userhash); + DCHECK(policies); + + for (const std::string& guid : new_cellular_policy_guids) { + const base::Value* network_policy = policies->GetPolicyByGuid(guid); + DCHECK(network_policy); + + const std::string* smdp_address = + policy_util::GetSMDPAddressFromONC(*network_policy); + if (features::IsESimPolicyEnabled() && smdp_address) { + NET_LOG(EVENT) + << "Found ONC configuration with SMDP: " << *smdp_address + << ". Start installing policy eSim profile with ONC config: " + << *network_policy; + if (cellular_policy_handler_) + cellular_policy_handler_->InstallESim(*smdp_address, *network_policy); + else + NET_LOG(ERROR) << "Unable to install eSIM. CellularPolicyHandler not " + "initialized."; + } else { + NET_LOG(EVENT) << "Skip installing policy eSIM either because " + "the eSIM policy feature is not enabled or the SMDP " + "address is missing from ONC."; + } + } +} + void ManagedNetworkConfigurationHandlerImpl::OnCellularPoliciesApplied( const NetworkProfile& profile) { - OnPoliciesApplied(profile); + const std::string& userhash = profile.userhash; + bool is_device_policy = userhash.empty(); + + // Inform observers that cellular policy application has finished. + // Only do this if non-cellular policy application is already done for + // `profile`, otherwise wait for OnPoliciesApplied to send the notification. + // Note that currently there is no separate observer signal for this. + if ((is_device_policy && device_policy_applied_) || + (!is_device_policy && user_policy_applied_)) { + for (auto& observer : observers_) + observer.PoliciesApplied(userhash); + } } void ManagedNetworkConfigurationHandlerImpl::OnPoliciesApplied( - const NetworkProfile& profile) { + const NetworkProfile& profile, + const base::flat_set<std::string>& new_cellular_policy_guids) { const std::string& userhash = profile.userhash; VLOG(1) << "Policy application for user '" << userhash << "' finished."; base::ThreadTaskRunnerHandle::Get()->DeleteSoon( FROM_HERE, policy_applicators_[userhash].release()); policy_applicators_.erase(userhash); + TriggerCellularPolicyApplication(profile, new_cellular_policy_guids); + if (base::Contains(queued_modified_policies_, userhash)) { base::flat_set<std::string> modified_policies; queued_modified_policies_[userhash].swap(modified_policies);
diff --git a/chromeos/network/managed_network_configuration_handler_impl.h b/chromeos/network/managed_network_configuration_handler_impl.h index 7b82c3d..c03fd117 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.h +++ b/chromeos/network/managed_network_configuration_handler_impl.h
@@ -119,6 +119,9 @@ void NotifyPolicyAppliedToNetwork( const std::string& service_path) const override; + void TriggerCellularPolicyApplication( + const NetworkProfile& profile, + const base::flat_set<std::string>& new_cellular_policy_guids); void OnCellularPoliciesApplied(const NetworkProfile& profile) override; bool AllowCellularSimLock() const override; @@ -141,7 +144,9 @@ const base::Value& new_properties, base::OnceClosure callback) override; - void OnPoliciesApplied(const NetworkProfile& profile) override; + void OnPoliciesApplied( + const NetworkProfile& profile, + const base::flat_set<std::string>& new_cellular_policy_guids) override; void Shutdown() override;
diff --git a/chromeos/network/managed_network_configuration_handler_unittest.cc b/chromeos/network/managed_network_configuration_handler_unittest.cc index ff2999e..8f8260d7 100644 --- a/chromeos/network/managed_network_configuration_handler_unittest.cc +++ b/chromeos/network/managed_network_configuration_handler_unittest.cc
@@ -1060,10 +1060,9 @@ InitializeStandardProfiles(); InitializeEuicc(); - // Check transfer to NetworkStateHandler. Expect one call for each policy - // application. + // Check transfer to NetworkStateHandler. EXPECT_CALL(*network_state_handler_, UpdateBlockedCellularNetworks(true)) - .Times(2); + .Times(1); // Set 'AllowOnlyPolicyCellularNetworks' policy. SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY, std::string(),
diff --git a/chromeos/network/network_policy_observer.h b/chromeos/network/network_policy_observer.h index f7f8ad2..f250967 100644 --- a/chromeos/network/network_policy_observer.h +++ b/chromeos/network/network_policy_observer.h
@@ -22,6 +22,10 @@ // Called every time a policy application for |userhash| finished. This is // only called once no more policies are pending for |userhash|. + // Because cellular policy application can be slow, the notification can be + // dispatched even if cellular policy application is still in progress. In + // this case, another |PoliciesApplied| notification will be invoked when + // cellular policy application is done. virtual void PoliciesApplied(const std::string& userhash) {} // Called every time a network is created or updated because of a policy.
diff --git a/chromeos/network/policy_applicator.cc b/chromeos/network/policy_applicator.cc index 9673bdc6a..4c46399cf 100644 --- a/chromeos/network/policy_applicator.cc +++ b/chromeos/network/policy_applicator.cc
@@ -18,7 +18,6 @@ #include "chromeos/ash/components/network/onc/onc_translator.h" #include "chromeos/components/onc/onc_signature.h" #include "chromeos/dbus/shill/shill_profile_client.h" -#include "chromeos/network/cellular_policy_handler.h" #include "chromeos/network/managed_cellular_pref_handler.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_type_pattern.h" @@ -70,20 +69,6 @@ return guid_value->GetString(); } -const std::string* GetSMDPAddressFromONC(const base::Value& onc_config) { - const std::string* type = - onc_config.FindStringKey(::onc::network_config::kType); - const base::Value* cellular_dict = - onc_config.FindKey(::onc::network_config::kCellular); - const std::string* smdp_address = nullptr; - - if (type && *type == ::onc::network_type::kCellular && cellular_dict && - cellular_dict->is_dict()) - smdp_address = cellular_dict->FindStringKey(::onc::cellular::kSMDPAddress); - - return smdp_address; -} - void CopyStringKey(const base::Value& old_shill_properties, base::Value* new_shill_properties, const std::string& property_key_name) { @@ -124,11 +109,9 @@ base::flat_map<std::string, base::Value> all_policies, base::Value global_network_config, ConfigurationHandler* handler, - CellularPolicyHandler* cellular_policy_handler, ManagedCellularPrefHandler* managed_cellular_pref_handler, base::flat_set<std::string>* modified_policy_guids) - : cellular_policy_handler_(cellular_policy_handler), - handler_(handler), + : handler_(handler), managed_cellular_pref_handler_(managed_cellular_pref_handler), profile_(profile), all_policies_(std::move(all_policies)), @@ -253,7 +236,8 @@ std::move(profile_entry_finished_callback)); const std::string* iccid = policy_util::GetIccidFromONC(*new_policy); - const std::string* smdp_address = GetSMDPAddressFromONC(*new_policy); + const std::string* smdp_address = + policy_util::GetSMDPAddressFromONC(*new_policy); if (was_managed && managed_cellular_pref_handler_ && iccid && smdp_address) { managed_cellular_pref_handler_->AddIccidSmdpPair(*iccid, *smdp_address); @@ -432,6 +416,22 @@ << "Create new managed network configurations in profile" << profile_.ToDebugString() << "."; + // PolicyApplicator does not handle applying new cellular policies, just + // collect these so they can be reported back to the caller. + for (base::flat_set<std::string>::iterator it = + remaining_policy_guids_.begin(); + it != remaining_policy_guids_.end();) { + const std::string& guid = *it; + const base::Value* network_policy = GetByGUID(all_policies_, guid); + DCHECK(network_policy); + if (policy_util::IsCellularPolicy(*network_policy)) { + new_cellular_policy_guids_.insert(guid); + it = remaining_policy_guids_.erase(it); + continue; + } + ++it; + } + if (remaining_policy_guids_.empty()) { NotifyConfigurationHandlerAndFinish(); return; @@ -440,41 +440,13 @@ // All profile entries were compared to policies. |remaining_policy_guids_| // contains all modified policies that didn't match any entry. For these // remaining policies, new configurations have to be created. - for (base::flat_set<std::string>::iterator it = - remaining_policy_guids_.begin(); - it != remaining_policy_guids_.end();) { - const std::string& guid = *it; + for (const std::string& guid : remaining_policy_guids_) { const base::Value* network_policy = GetByGUID(all_policies_, guid); DCHECK(network_policy); NET_LOG(EVENT) << "Creating new configuration managed by policy " << guid << " in profile " << profile_.ToDebugString() << "."; - if (policy_util::IsCellularPolicy(*network_policy)) { - const std::string* smdp_address = GetSMDPAddressFromONC(*network_policy); - if (features::IsESimPolicyEnabled() && smdp_address) { - NET_LOG(EVENT) - << "Found ONC configuration with SMDP: " << *smdp_address - << ". Start installing policy eSim profile with ONC config: " - << *network_policy; - if (cellular_policy_handler_) - cellular_policy_handler_->InstallESim(*smdp_address, *network_policy); - else - NET_LOG(ERROR) << "Unable to install eSIM. CellularPolicyHandler not " - "initialized."; - } else { - NET_LOG(EVENT) << "Skip installing policy eSIM either because " - "the eSIM policy feature is not enabled or the SMDP " - "address is missing from ONC."; - } - - it = remaining_policy_guids_.erase(it); - if (remaining_policy_guids_.empty()) { - NotifyConfigurationHandlerAndFinish(); - } - continue; - } - base::Value shill_dictionary = policy_util::CreateShillConfiguration( profile_, guid, &global_network_config_, network_policy, nullptr /* no user settings */); @@ -483,7 +455,6 @@ shill_dictionary, base::BindOnce(&PolicyApplicator::RemainingPolicyApplied, weak_ptr_factory_.GetWeakPtr(), guid)); - it++; } } @@ -498,7 +469,7 @@ void PolicyApplicator::NotifyConfigurationHandlerAndFinish() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); weak_ptr_factory_.InvalidateWeakPtrs(); - handler_->OnPoliciesApplied(profile_); + handler_->OnPoliciesApplied(profile_, new_cellular_policy_guids_); } } // namespace chromeos
diff --git a/chromeos/network/policy_applicator.h b/chromeos/network/policy_applicator.h index 61636f8..068d3ff 100644 --- a/chromeos/network/policy_applicator.h +++ b/chromeos/network/policy_applicator.h
@@ -19,7 +19,6 @@ namespace chromeos { -class CellularPolicyHandler; class ManagedCellularPrefHandler; class NetworkUIData; @@ -51,9 +50,14 @@ const base::Value& new_properties, base::OnceClosure callback) = 0; - // Called after all policies for |profile| were applied. At this point, the - // list of networks should be updated. - virtual void OnPoliciesApplied(const NetworkProfile& profile) = 0; + // Called after all policies for |profile| were applied except for new + // cellular policies. + // The set of new cellular policy guids is passed in + // `new_cellular_policy_guids`. + // At this point, the list of networks should be updated. + virtual void OnPoliciesApplied( + const NetworkProfile& profile, + const base::flat_set<std::string>& new_cellular_policy_guids) = 0; }; // |handler| must outlive this object. @@ -62,7 +66,6 @@ base::flat_map<std::string, base::Value> all_policies, base::Value global_network_config, ConfigurationHandler* handler, - CellularPolicyHandler* cellular_policy_handler, ManagedCellularPrefHandler* managed_cellular_pref_handler, base::flat_set<std::string>* modified_policy_guids); @@ -147,7 +150,10 @@ base::flat_set<std::string> remaining_policy_guids_; base::flat_set<std::string> pending_get_entry_calls_; - CellularPolicyHandler* cellular_policy_handler_ = nullptr; + // Contains GUIDs of new cellular policies so they can be reported back to + // the caller. + base::flat_set<std::string> new_cellular_policy_guids_; + ConfigurationHandler* handler_; ManagedCellularPrefHandler* managed_cellular_pref_handler_ = nullptr; NetworkProfile profile_;
diff --git a/chromeos/network/policy_util.cc b/chromeos/network/policy_util.cc index 7a6cd05..8c37d9aa 100644 --- a/chromeos/network/policy_util.cc +++ b/chromeos/network/policy_util.cc
@@ -406,6 +406,20 @@ return cellular_dict->FindStringKey(::onc::cellular::kICCID); } +const std::string* GetSMDPAddressFromONC(const base::Value& onc_config) { + const std::string* type = + onc_config.FindStringKey(::onc::network_config::kType); + const base::Value* cellular_dict = + onc_config.FindKey(::onc::network_config::kCellular); + const std::string* smdp_address = nullptr; + + if (type && (*type == ::onc::network_type::kCellular) && cellular_dict && + cellular_dict->is_dict()) + smdp_address = cellular_dict->FindStringKey(::onc::cellular::kSMDPAddress); + + return smdp_address; +} + } // namespace policy_util } // namespace chromeos
diff --git a/chromeos/network/policy_util.h b/chromeos/network/policy_util.h index 5ee7a23..b20c256a 100644 --- a/chromeos/network/policy_util.h +++ b/chromeos/network/policy_util.h
@@ -69,6 +69,11 @@ // is not a Cellular type ONC or no ICCID field is found. const std::string* GetIccidFromONC(const base::Value& onc_config); +// Returns the Cellular.SMDPAddress ONC field of the passed ONC +// NetworkConfiguration if it is a Cellular NetworkConfiguration. +// If there is no SMDPAddress, returns nullptr. +const std::string* GetSMDPAddressFromONC(const base::Value& onc_config); + } // namespace policy_util } // namespace chromeos
diff --git a/chromeos/network/profile_policies.cc b/chromeos/network/profile_policies.cc index a9a62ccd..f100ba8 100644 --- a/chromeos/network/profile_policies.cc +++ b/chromeos/network/profile_policies.cc
@@ -10,6 +10,10 @@ #include "base/containers/flat_set.h" #include "base/values.h" +#include "chromeos/components/onc/onc_signature.h" +#include "chromeos/components/onc/onc_utils.h" +#include "chromeos/components/onc/variable_expander.h" +#include "chromeos/network/client_cert_util.h" #include "chromeos/network/policy_util.h" #include "components/device_event_log/device_event_log.h" #include "components/onc/onc_constants.h" @@ -25,32 +29,112 @@ shill_properties); } +base::flat_map<std::string, std::string> GetAllExpansions( + const base::flat_map<std::string, std::string>& profile_wide_expansions, + const client_cert::ResolvedCert& resolved_cert) { + base::flat_map<std::string, std::string> result; + result.insert(profile_wide_expansions.begin(), profile_wide_expansions.end()); + if (resolved_cert.status() == + client_cert::ResolvedCert::Status::kCertMatched) { + result.insert(resolved_cert.variable_expansions().begin(), + resolved_cert.variable_expansions().end()); + } + return result; +} + +base::Value DefaultRuntimeValuesSetter( + const base::Value& onc_network_configuration, + const base::flat_map<std::string, std::string>& profile_wide_expansions, + const client_cert::ResolvedCert& resolved_cert) { + // TODO(b/215163180): Change this to return a NONE base::Value instead of + // cloning if the variable expansion doesn't change anything when this is the + // only caller of ExpandStringsInOncObject. + base::Value expanded = onc_network_configuration.Clone(); + VariableExpander variable_expander( + GetAllExpansions(profile_wide_expansions, resolved_cert)); + onc::ExpandStringsInOncObject(onc::kNetworkConfigurationSignature, + variable_expander, &expanded); + client_cert::SetResolvedCertInOnc(resolved_cert, expanded); + return expanded; +} + } // namespace -ProfilePolicies::NetworkPolicy::NetworkPolicy(base::Value onc_policy) - : onc_policy_(std::move(onc_policy)) {} +ProfilePolicies::NetworkPolicy::NetworkPolicy(const ProfilePolicies* parent, + base::Value onc_policy) + : parent_(parent), original_policy_(std::move(onc_policy)) { + // There could already be profile-wide variable expansions (through parent_). + ReapplyRuntimeValues(); +} + ProfilePolicies::NetworkPolicy::~NetworkPolicy() = default; ProfilePolicies::NetworkPolicy::NetworkPolicy(NetworkPolicy&& other) = default; ProfilePolicies::NetworkPolicy& ProfilePolicies::NetworkPolicy::operator=( - ProfilePolicies::NetworkPolicy&& other) = default; + NetworkPolicy&& other) = default; -bool ProfilePolicies::NetworkPolicy::UpdateFrom(const base::Value& new_policy) { - if (new_policy == onc_policy_) - return false; - onc_policy_ = new_policy.Clone(); - return true; -} - -const base::Value* ProfilePolicies::NetworkPolicy::GetPolicy() const { - return &onc_policy_; +ProfilePolicies::ChangeEffect ProfilePolicies::NetworkPolicy::UpdateFrom( + const base::Value& new_onc_policy) { + if (new_onc_policy == original_policy_) + return ChangeEffect::kNoChange; + original_policy_ = new_onc_policy.Clone(); + ReapplyRuntimeValues(); + return ChangeEffect::kEffectivePolicyChanged; } ProfilePolicies::ProfilePolicies() : shill_properties_matcher_( - base::BindRepeating(&DefaultShillPropertiesMatcher)) {} + base::BindRepeating(&DefaultShillPropertiesMatcher)), + runtime_values_setter_(base::BindRepeating(&DefaultRuntimeValuesSetter)) { +} ProfilePolicies::~ProfilePolicies() = default; +ProfilePolicies::ChangeEffect +ProfilePolicies::NetworkPolicy::SetResolvedClientCertificate( + client_cert::ResolvedCert resolved_cert) { + if (resolved_cert_ == resolved_cert) + return ChangeEffect::kNoChange; + resolved_cert_ = std::move(resolved_cert); + return ReapplyRuntimeValues(); +} + +ProfilePolicies::ChangeEffect +ProfilePolicies::NetworkPolicy::OnProfileWideExpansionsChanged() { + return ReapplyRuntimeValues(); +} + +const base::Value& ProfilePolicies::NetworkPolicy::GetOriginalPolicy() const { + return original_policy_; +} + +const base::Value& ProfilePolicies::NetworkPolicy::GetPolicyWithRuntimeValues() + const { + if (!policy_with_runtime_values_.has_value()) { + // Memory optimization to avoid storing the same value twice if setting + // runtime values resulted in no change. + return original_policy_; + } + return policy_with_runtime_values_.value(); +} + +ProfilePolicies::ChangeEffect +ProfilePolicies::NetworkPolicy::ReapplyRuntimeValues() { + absl::optional<base::Value> old_policy_with_runtime_values = + std::move(policy_with_runtime_values_); + + policy_with_runtime_values_ = parent_->runtime_values_setter_.Run( + original_policy_, parent_->profile_wide_expansions_, resolved_cert_); + if (policy_with_runtime_values_ == original_policy_) { + // Memory optimization to avoid storing the same value twice if variable + // expansion had no effect. + policy_with_runtime_values_ = {}; + } + + return old_policy_with_runtime_values == policy_with_runtime_values_ + ? ChangeEffect::kNoChange + : ChangeEffect::kEffectivePolicyChanged; +} + base::flat_set<std::string> ProfilePolicies::ApplyOncNetworkConfigurationList( const base::Value& network_configs_onc) { DCHECK(network_configs_onc.is_list()); @@ -73,12 +157,13 @@ NetworkPolicy* existing_policy = FindPolicy(guid); if (!existing_policy) { guid_to_policy_.insert( - std::make_pair(guid, NetworkPolicy(network.Clone()))); + std::make_pair(guid, NetworkPolicy(this, network.Clone()))); new_or_modified_guids.insert(guid); continue; } removed_guids.erase(guid); - if (existing_policy->UpdateFrom(network)) { + if (existing_policy->UpdateFrom(network) == + ChangeEffect::kEffectivePolicyChanged) { new_or_modified_guids.insert(guid); } } @@ -96,16 +181,48 @@ global_network_config_ = global_network_config.Clone(); } +base::flat_set<std::string> ProfilePolicies::SetProfileWideExpansions( + base::flat_map<std::string, std::string> expansions) { + if (profile_wide_expansions_ == expansions) + return {}; + profile_wide_expansions_ = std::move(expansions); + base::flat_set<std::string> modified_guids; + for (auto& pair : guid_to_policy_) { + if (pair.second.OnProfileWideExpansionsChanged() == + ChangeEffect::kEffectivePolicyChanged) { + modified_guids.insert(pair.first); + } + } + return modified_guids; +} + +bool ProfilePolicies::SetResolvedClientCertificate( + const std::string& guid, + client_cert::ResolvedCert resolved_cert) { + base::flat_set<std::string> modified_guids; + NetworkPolicy* policy = FindPolicy(guid); + if (!policy) + return false; + return policy->SetResolvedClientCertificate(std::move(resolved_cert)) == + ChangeEffect::kEffectivePolicyChanged; +} + const base::Value* ProfilePolicies::GetPolicyByGuid( const std::string& guid) const { const NetworkPolicy* policy = FindPolicy(guid); - return policy ? policy->GetPolicy() : nullptr; + return policy ? &policy->GetPolicyWithRuntimeValues() : nullptr; +} + +const base::Value* ProfilePolicies::GetOriginalPolicyByGuid( + const std::string& guid) const { + const NetworkPolicy* policy = FindPolicy(guid); + return policy ? &policy->GetOriginalPolicy() : nullptr; } bool ProfilePolicies::HasPolicyMatchingShillProperties( const base::Value& shill_properties) const { for (const auto& [guid, policy] : guid_to_policy_) { - if (shill_properties_matcher_.Run(*(policy.GetPolicy()), + if (shill_properties_matcher_.Run(policy.GetPolicyWithRuntimeValues(), shill_properties)) { return true; } @@ -118,7 +235,8 @@ std::vector<std::pair<std::string, base::Value>> result; result.reserve(guid_to_policy_.size()); for (const auto& [guid, policy] : guid_to_policy_) { - result.push_back(std::make_pair(guid, policy.GetPolicy()->Clone())); + result.push_back( + std::make_pair(guid, policy.GetPolicyWithRuntimeValues().Clone())); } return base::flat_map<std::string, base::Value>(std::move(result)); } @@ -128,6 +246,11 @@ shill_properties_matcher_ = shill_properties_matcher; } +void ProfilePolicies::SetRuntimeValuesSetterForTesting( + const RuntimeValuesSetter& runtime_values_setter) { + runtime_values_setter_ = runtime_values_setter; +} + base::flat_set<std::string> ProfilePolicies::GetAllPolicyGuids() const { std::vector<std::string> result; result.reserve(guid_to_policy_.size());
diff --git a/chromeos/network/profile_policies.h b/chromeos/network/profile_policies.h index cb2695e..b016dd8 100644 --- a/chromeos/network/profile_policies.h +++ b/chromeos/network/profile_policies.h
@@ -12,20 +12,30 @@ #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/values.h" +#include "chromeos/network/client_cert_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace chromeos { // Stores network policies for a shill profile. // Understands some ONC (OpenNetworkConfiguration) concepts such as -// NetworkConfiguration. -// TODO(b/209084821): Add support for variable replacement. +// NetworkConfiguration and ONC variable expansion ( +// https://chromium.googlesource.com/chromium/src/+/main/components/onc/docs/onc_spec.md#String-Expansions +// ). +// Variable expansions can be set on the ProfilePolicies level using +// ProfilePolicies::SetProfileWideExpansions where they apply to all network +// configurations within that ProfilePolicies. +// On a single network policy level (keyed by the network poilcy's GUID), +// ProfilePolicies::SetResolvedClientCertificate can be used to set the resolved +// certificate including variable expansions extracted from that certificate. class COMPONENT_EXPORT(CHROMEOS_NETWORK) ProfilePolicies { public: + enum class ChangeEffect { kNoChange, kEffectivePolicyChanged }; + // Stores policies for a network. class NetworkPolicy { public: - NetworkPolicy(base::Value onc_policy); + NetworkPolicy(const ProfilePolicies* parent, base::Value onc_policy); ~NetworkPolicy(); NetworkPolicy(const NetworkPolicy& other) = delete; @@ -36,13 +46,43 @@ // Replaces the current policy with |new_policy|, which should be an ONC // NetworkConfiguration. - // If this NetworkPolicy has changed, returns true. Otherwise returns false. - bool UpdateFrom(const base::Value& new_policy); + // Returns an indication about whether the effective policy has changed as a + // result of this call. + ChangeEffect UpdateFrom(const base::Value& new_onc_policy); - const base::Value* GetPolicy() const; + // Sets the resolved client certificate for this network. + // Returns an indication about whether the effective policy has changed as a + // result of this call. + ChangeEffect SetResolvedClientCertificate( + client_cert::ResolvedCert resolved_cert); + + // Re-applies the profile-wide expansions from |parent|. Should be called by + // |parent| whenever profile-wide expansions have changed. + // Returns an indication about whether the effective policy has changed as a + // result of this call. + ChangeEffect OnProfileWideExpansionsChanged(); + + // Returns the original ONC policy without runtime values. + const base::Value& GetOriginalPolicy() const; + + // Returns the effective ONC policy with runtime values set. + const base::Value& GetPolicyWithRuntimeValues() const; private: - base::Value onc_policy_; + // Applies the runtime values. + ChangeEffect ReapplyRuntimeValues(); + + const ProfilePolicies* parent_; + + client_cert::ResolvedCert resolved_cert_ = + client_cert::ResolvedCert::NotKnownYet(); + + base::Value original_policy_; + + // The ONC NetworkConfiguration with runtime values set. If this is absent, + // it means that setting runtime values didn't change anything compared to + // |original_onc_policy_|. + absl::optional<base::Value> policy_with_runtime_values_; }; // Used to check whether an ONC NetworkConfiguration passed in @@ -52,6 +92,11 @@ base::RepeatingCallback<bool(const base::Value& onc_network_configuration, const base::Value& shill_properties)>; + using RuntimeValuesSetter = base::RepeatingCallback<base::Value( + const base::Value& onc_network_configuration, + const base::flat_map<std::string, std::string>& profile_wide_expansions, + const client_cert::ResolvedCert& resolved_cert)>; + ProfilePolicies(); ~ProfilePolicies(); @@ -69,11 +114,35 @@ // |global_network_config|, which must be a DICTIONARY base::Value. void SetGlobalNetworkConfig(const base::Value& global_network_config); + // Sets the ONC variable expansions which should apply to all + // NetworkConfigurations within this ProfilePolicies instance. + // Returns the set of policy GUIDs which have effectively changed due to this. + base::flat_set<std::string> SetProfileWideExpansions( + base::flat_map<std::string, std::string> expansions); + + // Sets the resolved client certificate for the ONC NetworkConfiguration + // specified by |guid|. + // Returns true if the policy for |guid| has effectively changed, false + // otherwise. + // If |guid| does not refer to a NetworkConfiguration from policy, the + // |resolved_cert| will be lost and false is returned. + bool SetResolvedClientCertificate(const std::string& guid, + client_cert::ResolvedCert resolved_cert); + // Returns the policy for |guid| or nullptr if no such policy exists. - // The returned pointer remains valid as long as this instance is valid and is - // not modified (e.g. by calls to ApplyOncNetworkConfigurations). + // If the policy value contained ONC variable expansions, they will be + // expanded in the returned value. The returned pointer remains valid as long + // as this instance is valid and is not modified (e.g. by calls to + // SetProfileWideExpansions). const base::Value* GetPolicyByGuid(const std::string& guid) const; + // Returns the policy for |guid| without runtime values set (i.e. the + // variable placeholders such as ${LOGIN_EMAIL} will still be present), or + // nullptr if no such policy exists. The returned pointer remains valid as + // long as this instance is valid and is not modified (e.g. by calls to + // SetProfileWideExpansions). + const base::Value* GetOriginalPolicyByGuid(const std::string& guid) const; + // Returns the GlobalNetworkConfiguration ONC Dictionary. // This will never return nullptr (if no GlobalNetworkConfiguration has been // set, it will return a pointer to an empty DICT base::Value). It returns a @@ -91,6 +160,8 @@ const base::Value& shill_properties) const; // Returns the map of network policy GUID to ONC NetworkConfiguration. + // The returned policy values will have ONC variables expanded, if they + // contained any. // This clones all values in the map. base::flat_map<std::string, base::Value> GetGuidToPolicyMap() const; @@ -105,14 +176,28 @@ void SetShillPropertiesMatcherForTesting( const ShillPropertiesMatcher& shill_properties_matcher); + // Sets the function which will be executed to set run-time values in the ONC + // NetworkConfiguration. + // This is useful so the unit test of this class does not have to depend on + // the actual ONC logic (which is unit tested elsewhere). + void SetRuntimeValuesSetterForTesting( + const RuntimeValuesSetter& runtime_values_setter); + private: NetworkPolicy* FindPolicy(const std::string& guid); const NetworkPolicy* FindPolicy(const std::string& guid) const; ShillPropertiesMatcher shill_properties_matcher_; + // Sets values computed at runtime into an ONC NetworkConfiguration + // dictionary (currently variable expansions and a resolved client + // certificate). + RuntimeValuesSetter runtime_values_setter_; + base::flat_map<std::string, NetworkPolicy> guid_to_policy_; base::Value global_network_config_{base::Value::Type::DICTIONARY}; + + base::flat_map<std::string, std::string> profile_wide_expansions_; }; } // namespace chromeos
diff --git a/chromeos/network/profile_policies_unittest.cc b/chromeos/network/profile_policies_unittest.cc index 6f3d2375e..d4b637a 100644 --- a/chromeos/network/profile_policies_unittest.cc +++ b/chromeos/network/profile_policies_unittest.cc
@@ -8,6 +8,7 @@ #include "base/containers/flat_set.h" #include "base/test/values_test_util.h" #include "base/values.h" +#include "chromeos/network/client_cert_util.h" #include "components/onc/onc_constants.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -54,10 +55,58 @@ return onc_network_configuration == shill_properties; } +// A runtime values setter which doesn't change its input ONC dictionary. +// Useful for emulating that setting runtime values resulted in no change from +// the "original" ONC dictionary. +base::Value NoOp( + const base::Value& onc_network_configuration, + const base::flat_map<std::string, std::string>& profile_wide_expansions, + const client_cert::ResolvedCert& resolved_cert) { + return onc_network_configuration.Clone(); +} + +// A RuntimeValuesSetter which injects its inputs as +// dictionary keys. Useful for checking behavior when variable +// setting runtime values actually changes the ONC dictionary, and for easy +// verification of the values that have been passed to the RuntimeValuesSetter. +base::Value Inject( + const base::Value& onc_network_configuration, + const base::flat_map<std::string, std::string>& profile_wide_expansions, + const client_cert::ResolvedCert& resolved_cert) { + base::Value result = onc_network_configuration.Clone(); + + base::Value::Dict profile_wide_expansions_dict; + for (const auto& pair : profile_wide_expansions) { + profile_wide_expansions_dict.Set(pair.first, base::Value(pair.second)); + } + result.SetKey("profile_wide_expansions", + base::Value(std::move(profile_wide_expansions_dict))); + + if (resolved_cert.status() == + client_cert::ResolvedCert::Status::kNothingMatched) { + base::Value::Dict cert_dict; + cert_dict.Set("status", "no cert"); + result.SetKey("cert_info", base::Value(std::move(cert_dict))); + } else if (resolved_cert.status() == + client_cert::ResolvedCert::Status::kCertMatched) { + base::Value::Dict cert_dict; + for (const auto& pair : resolved_cert.variable_expansions()) { + cert_dict.Set(pair.first, base::Value(pair.second)); + } + cert_dict.Set("slot_id", resolved_cert.slot_id()); + cert_dict.Set("pkcs11_id", resolved_cert.pkcs11_id()); + result.SetKey("cert_info", base::Value(std::move(cert_dict))); + } + + return result; +} + +} // namespace + using ProfilePoliciesTest = ::testing::Test; // Calls GetGlobalNetworkConfig when no GlobalNetworkConfig has been set yet. -TEST_F(ProfilePoliciesTest, GlobalNetworkConfigIsEmpty) { +TEST(ProfilePoliciesTest, GlobalNetworkConfigIsEmpty) { ProfilePolicies profile_policies; ASSERT_TRUE(profile_policies.GetGlobalNetworkConfig()); ASSERT_TRUE(profile_policies.GetGlobalNetworkConfig()->is_dict()); @@ -65,7 +114,7 @@ } // Sets / retrieves GlobalNetworkConfig. -TEST_F(ProfilePoliciesTest, SetAndOverwriteGlobalNetworkConfig) { +TEST(ProfilePoliciesTest, SetAndOverwriteGlobalNetworkConfig) { base::Value global_network_config_1(base::Value::Type::DICTIONARY); global_network_config_1.SetKey("key1", base::Value("value1")); @@ -85,7 +134,7 @@ } // Tests accessors to per-network policies when no policy has been set. -TEST_F(ProfilePoliciesTest, NoNetworkPolicy) { +TEST(ProfilePoliciesTest, NoNetworkPolicy) { ProfilePolicies profile_policies; EXPECT_EQ(profile_policies.GetPolicyByGuid("guid"), nullptr); EXPECT_THAT(profile_policies.GetAllPolicyGuids(), IsEmpty()); @@ -95,7 +144,7 @@ // Applies a network policy and checks accessors to per-network policies. // The original policy (none) had no network configs. // The new poilcy has no network configs. -TEST_F(ProfilePoliciesTest, ApplyOncNetworkConfigurationListZeroToZero) { +TEST(ProfilePoliciesTest, ApplyOncNetworkConfigurationListZeroToZero) { base::Value network_configs(base::Value::Type::LIST); ProfilePolicies profile_policies; @@ -110,7 +159,7 @@ // Applies a network policy and checks accessors to per-network policies. // The original policy (none) had no network configs. // The new poilcy has one network config. -TEST_F(ProfilePoliciesTest, ApplyOncNetworkConfigurationListZeroToOne) { +TEST(ProfilePoliciesTest, ApplyOncNetworkConfigurationListZeroToOne) { base::Value network_config_1 = NetworkConfig("guid1"); base::Value network_configs = NetworkConfigsList({&network_config_1}); @@ -130,7 +179,7 @@ // Applies a network policy and checks accessors to per-network policies. // Goes from no policy (0 networks) -> policy with 1 network -> policy with 0 // networks. -TEST_F(ProfilePoliciesTest, ApplyOncNetworkConfigurationListOneToZero) { +TEST(ProfilePoliciesTest, ApplyOncNetworkConfigurationListOneToZero) { base::Value network_config_1 = NetworkConfig("guid1"); base::Value network_configs_orig = NetworkConfigsList({&network_config_1}); @@ -149,7 +198,7 @@ // Applies a network policy and checks accessors to per-network policies. // Tests re-application of exactly the same policy (no effective change). -TEST_F(ProfilePoliciesTest, ApplyOncNetworkConfigurationListNoChange) { +TEST(ProfilePoliciesTest, ApplyOncNetworkConfigurationListNoChange) { base::Value network_config_1 = NetworkConfig("guid1"); base::Value network_configs_orig = NetworkConfigsList({&network_config_1}); @@ -168,7 +217,7 @@ // Applies a policy with a network config "guid1". // Applies another policy where "guid1" has changed contents. // Tests that "guid1" is reported as changed and has the new contents. -TEST_F(ProfilePoliciesTest, ApplyOncNetworkConfigurationListChange) { +TEST(ProfilePoliciesTest, ApplyOncNetworkConfigurationListChange) { base::Value network_config_orig = NetworkConfig("guid1"); base::Value network_configs_orig = NetworkConfigsList({&network_config_orig}); @@ -195,7 +244,7 @@ // Applies a network policy with multiple NetworkConfiguration elements and // checks accessors to per-network policies. -TEST_F(ProfilePoliciesTest, MultipleElemetns) { +TEST(ProfilePoliciesTest, MultipleElemetns) { base::Value network_config_1 = NetworkConfig("guid1"); network_config_1.SetKey("test1", base::Value("value1")); base::Value network_config_2 = NetworkConfig("guid2"); @@ -214,7 +263,7 @@ } // Tests HasPolicyMatchingShillProperties for the case that no policy matches. -TEST_F(ProfilePoliciesTest, HasPolicyMatchingShillPropertiesNoMatch) { +TEST(ProfilePoliciesTest, HasPolicyMatchingShillPropertiesNoMatch) { base::Value network_config_1 = NetworkConfig("guid1"); base::Value network_configs_orig = NetworkConfigsList({&network_config_1}); @@ -228,7 +277,7 @@ } // Tests HasPolicyMatchingShillProperties for the case that a policy matches. -TEST_F(ProfilePoliciesTest, HasPolicyMatchingShillPropertiesMatch) { +TEST(ProfilePoliciesTest, HasPolicyMatchingShillPropertiesMatch) { base::Value network_config_1 = NetworkConfig("guid1"); base::Value network_config_2 = NetworkConfig("guid2"); network_config_2.SetKey("marker", base::Value("value")); @@ -244,5 +293,295 @@ profile_policies.HasPolicyMatchingShillProperties(network_config_2)); } -} // namespace +// Tests that profile-wide expansions apply if they were configured before the +// NetworkConfiguration was applied. +TEST(ProfilePoliciesTest, ProfileWideExpansionsAlreadyExist) { + base::Value network_config = NetworkConfig("guid1"); + base::Value network_configs = NetworkConfigsList({&network_config}); + + ProfilePolicies profile_policies; + + // Replace the variable expander with one which is simply injecting all + // expansions as top-level dictionary keys instead. + profile_policies.SetRuntimeValuesSetterForTesting( + base::BindRepeating(&Inject)); + + { + base::flat_set<std::string> modified_guids = + profile_policies.SetProfileWideExpansions( + {{"profileWideVar", "profileWideValue"}}); + EXPECT_THAT(modified_guids, IsEmpty()); + } + + profile_policies.ApplyOncNetworkConfigurationList(network_configs); + + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + ElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + } + })")))); +} + +// Tests that nothing happens when the variable expansions change if no +// NetworkConfiguration depends on them. This is emulated by using the NoOp +// expander (in reality it would happen if no network configuration contains a +// known expansion). +TEST(ProfilePoliciesTest, ChangeNoEffect) { + base::Value network_config_1 = NetworkConfig("guid1"); + base::Value network_configs = NetworkConfigsList({&network_config_1}); + + ProfilePolicies profile_policies; + profile_policies.SetRuntimeValuesSetterForTesting(base::BindRepeating(&NoOp)); + profile_policies.ApplyOncNetworkConfigurationList(network_configs); + + base::flat_set<std::string> modified_guids = + profile_policies.SetProfileWideExpansions( + {{"profileWideVar", "profileWideValue"}}); + EXPECT_THAT(modified_guids, IsEmpty()); + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre( + Pair("guid1", base::test::IsJson(network_config_1)))); +} + +// Tests that when variable expansions (both profile-wide and network-specific) +// change and a NetworkConfiguration depends on them, the policy value with +// expansions is updated accordingly and the setter for the expansions returns +// back the set of affected NetworkConfiguration GUIDs to its caller. +TEST(ProfilePoliciesTest, ExpansionsChangeAffectsNetworkConfiguration) { + base::Value network_config_1 = NetworkConfig("guid1"); + base::Value network_config_2 = NetworkConfig("guid2"); + base::Value network_configs = + NetworkConfigsList({&network_config_1, &network_config_2}); + + ProfilePolicies profile_policies; + + // Replace the variable expander with one which is simply injecting all + // expansions as top-level dictionary keys instead. + profile_policies.SetRuntimeValuesSetterForTesting( + base::BindRepeating(&Inject)); + + profile_policies.ApplyOncNetworkConfigurationList(network_configs); + + { + base::flat_set<std::string> modified_guids = + profile_policies.SetProfileWideExpansions( + {{"profileWideVar", "profileWideValue"}}); + EXPECT_THAT(modified_guids, UnorderedElementsAre("guid1", "guid2")); + } + + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + } + })")), + Pair("guid2", base::test::IsJson(R"( + { + "GUID": "guid2", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + } + })")))); + + { + bool change_had_effect = profile_policies.SetResolvedClientCertificate( + "guid1", client_cert::ResolvedCert::CertMatched( + 1, "pkcs11_id", {{"certVar", "certVarValue"}})); + EXPECT_TRUE(change_had_effect); + } + + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + }, + "cert_info": { + "slot_id": 1, + "pkcs11_id": "pkcs11_id", + "certVar": "certVarValue" + } + })")), + Pair("guid2", base::test::IsJson(R"( + { + "GUID": "guid2", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + } + })")))); + + { + bool change_had_effect = profile_policies.SetResolvedClientCertificate( + "guid1", client_cert::ResolvedCert::NothingMatched()); + EXPECT_TRUE(change_had_effect); + } + + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + }, + "cert_info": { + "status": "no cert" + } + })")), + Pair("guid2", base::test::IsJson(R"( + { + "GUID": "guid2", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + } + })")))); + + { + base::flat_set<std::string> modified_guids = + profile_policies.SetProfileWideExpansions({}); + EXPECT_THAT(modified_guids, UnorderedElementsAre("guid1", "guid2")); + } + + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": {}, + "cert_info": { + "status": "no cert" + } + })")), + Pair("guid2", base::test::IsJson(R"( + { + "GUID": "guid2", + "profile_wide_expansions": {} + })")))); +} + +// Tests that variable expansions (both profile-wide and per-network) are +// applied when a NetworkConfiguration changes. +TEST(ProfilePoliciesTest, NetworkConfigurationChangeWithExistingExpansions) { + ProfilePolicies profile_policies; + + // Replace the variable expander with one which is simply injecting all + // expansions as top-level dictionary keys instead. + profile_policies.SetRuntimeValuesSetterForTesting( + base::BindRepeating(&Inject)); + + { + base::flat_set<std::string> modified_guids = + profile_policies.SetProfileWideExpansions( + {{"profileWideVar", "profileWideValue"}}); + EXPECT_THAT(modified_guids, IsEmpty()); + } + + { + base::Value network_config_1 = NetworkConfig("guid1"); + base::Value network_configs = NetworkConfigsList({&network_config_1}); + base::flat_set<std::string> modified_guids = + profile_policies.ApplyOncNetworkConfigurationList(network_configs); + EXPECT_THAT(modified_guids, UnorderedElementsAre("guid1")); + } + + { + bool change_had_effect = profile_policies.SetResolvedClientCertificate( + "guid1", client_cert::ResolvedCert::CertMatched( + 1, "pkcs11_id", {{"certVar", "certVarValue"}})); + EXPECT_TRUE(change_had_effect); + } + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + }, + "cert_info": { + "slot_id": 1, + "pkcs11_id": "pkcs11_id", + "certVar": "certVarValue" + } + })")))); + { + base::Value network_config_1 = NetworkConfig("guid1"); + network_config_1.SetKey("modified", base::Value("yes")); + base::Value network_configs = NetworkConfigsList({&network_config_1}); + base::flat_set<std::string> modified_guids = + profile_policies.ApplyOncNetworkConfigurationList(network_configs); + EXPECT_THAT(modified_guids, UnorderedElementsAre("guid1")); + } + EXPECT_THAT(profile_policies.GetGuidToPolicyMap(), + UnorderedElementsAre(Pair("guid1", base::test::IsJson(R"( + { + "GUID": "guid1", + "modified": "yes", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + }, + "cert_info": { + "slot_id": 1, + "pkcs11_id": "pkcs11_id", + "certVar": "certVarValue" + } + })")))); +} + +// Tests that GetOriginalPolicyByGuid returns the policy without +// variable expansions. +TEST(ProfilePoliciesTest, GetOriginalPolicyByGuid) { + base::Value network_config_1 = NetworkConfig("guid1"); + base::Value network_configs = NetworkConfigsList({&network_config_1}); + + ProfilePolicies profile_policies; + + // Replace the variable expander with one which is simply injecting all + // expansions as top-level dictionary keys instead. + profile_policies.SetRuntimeValuesSetterForTesting( + base::BindRepeating(&Inject)); + + profile_policies.ApplyOncNetworkConfigurationList(network_configs); + + profile_policies.SetProfileWideExpansions( + {{"profileWideVar", "profileWideValue"}}); + const base::Value* policy_with_expansions = + profile_policies.GetPolicyByGuid("guid1"); + const base::Value* policy_without_expansions = + profile_policies.GetOriginalPolicyByGuid("guid1"); + ASSERT_TRUE(policy_with_expansions); + ASSERT_TRUE(policy_without_expansions); + + EXPECT_THAT(*policy_with_expansions, base::test::IsJson(R"( + { + "GUID": "guid1", + "profile_wide_expansions": { + "profileWideVar": "profileWideValue" + } + })")); + EXPECT_THAT(*policy_without_expansions, base::test::IsJson(R"( + { + "GUID": "guid1" + })")); +} + +// Tests that setting per-network variable expansions doesn't do anything (and +// doesn't crash) if the GUID is unknown. +TEST(ProfilePoliciesTest, SetResolvedClientCertificateUnknownGuid) { + ProfilePolicies profile_policies; + + // Replace the variable expander with one which is simply injecting all + // expansions as top-level dictionary keys instead. + profile_policies.SetRuntimeValuesSetterForTesting( + base::BindRepeating(&Inject)); + + bool change_had_effect = profile_policies.SetResolvedClientCertificate( + "unknown_guid", client_cert::ResolvedCert::CertMatched( + 1, "pkcs11_id", {{"var1", "value1"}})); + EXPECT_FALSE(change_had_effect); +} + } // namespace chromeos
diff --git a/chromeos/services/assistant/DEPS b/chromeos/services/assistant/DEPS index 13ac512..72acd96e 100644 --- a/chromeos/services/assistant/DEPS +++ b/chromeos/services/assistant/DEPS
@@ -1,3 +1,7 @@ +# TODO(https://crbug.com/1164001): When this file is edited, same file in +# //chromeos/ash/services/assistant should be updated as well. We need to sync +# both files until the migration is done. + include_rules = [ "+ash/components/audio", "+ash/public",
diff --git a/chromeos/services/assistant/public/cpp/BUILD.gn b/chromeos/services/assistant/public/cpp/BUILD.gn index 8480fb2..97d613c 100644 --- a/chromeos/services/assistant/public/cpp/BUILD.gn +++ b/chromeos/services/assistant/public/cpp/BUILD.gn
@@ -48,4 +48,8 @@ "//chromeos/ash/components/assistant:buildflags", "//components/prefs", ] + + if (enable_cros_libassistant) { + deps += [ "//chromeos/assistant/internal:buildflags" ] + } }
diff --git a/chromeos/services/assistant/public/cpp/features.cc b/chromeos/services/assistant/public/cpp/features.cc index 16a779c8..e65ca39 100644 --- a/chromeos/services/assistant/public/cpp/features.cc +++ b/chromeos/services/assistant/public/cpp/features.cc
@@ -6,6 +6,12 @@ #include "ash/constants/ash_features.h" #include "base/feature_list.h" +#include "build/buildflag.h" +#include "chromeos/ash/components/assistant/buildflags.h" + +#if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) +#include "chromeos/assistant/internal/buildflags.h" +#endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT) namespace chromeos { namespace assistant { @@ -96,7 +102,16 @@ } bool IsLibAssistantV2Enabled() { +// Enforce V2 when using the prebuilt library. +#if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) +#if BUILDFLAG(IS_PREBUILT_LIBASSISTANT) + return true; +#else return base::FeatureList::IsEnabled(kEnableLibAssistantV2); +#endif // BUILDFLAG(IS_PREBUILT_LIBASSISTANT) +#else + return false; +#endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT) } } // namespace features
diff --git a/chromeos/services/cros_healthd/DIR_METADATA b/chromeos/services/cros_healthd/DIR_METADATA index 5fd9089..f39086f 100644 --- a/chromeos/services/cros_healthd/DIR_METADATA +++ b/chromeos/services/cros_healthd/DIR_METADATA
@@ -1,5 +1,5 @@ buganizer: { - component_id: 582701 + component_id: 982097 } monorail { component: "OS>Software>Enterprise"
diff --git a/chromeos/services/cros_healthd/OWNERS b/chromeos/services/cros_healthd/OWNERS index de7367c..028816b 100644 --- a/chromeos/services/cros_healthd/OWNERS +++ b/chromeos/services/cros_healthd/OWNERS
@@ -1,3 +1,3 @@ menghuan@chromium.org kerker@chromium.org -chungsheng@chromium.org +chungsheng@google.com
diff --git a/chromeos/services/cros_healthd/private/cpp/data_collector.cc b/chromeos/services/cros_healthd/private/cpp/data_collector.cc index 5de888e1..6af1068 100644 --- a/chromeos/services/cros_healthd/private/cpp/data_collector.cc +++ b/chromeos/services/cros_healthd/private/cpp/data_collector.cc
@@ -11,6 +11,7 @@ #include "base/no_destructor.h" #include "base/notreached.h" #include "base/posix/eintr_wrapper.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -129,6 +130,7 @@ } void GetTouchscreenDevicesOnUIThread( + scoped_refptr<base::SequencedTaskRunner> task_runner, DataCollectorImpl::GetTouchscreenDevicesCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -150,16 +152,16 @@ result->has_stylus_garage_switch = device.has_stylus_garage_switch; results.push_back(std::move(result)); } - content::GetIOThreadTaskRunner({})->PostTask( + task_runner->PostTask( FROM_HERE, base::BindOnce(std::move(callback), std::move(results))); } void DataCollectorImpl::GetTouchscreenDevices( GetTouchscreenDevicesCallback callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&GetTouchscreenDevicesOnUIThread, std::move(callback))); + FROM_HERE, base::BindOnce(&GetTouchscreenDevicesOnUIThread, + base::SequencedTaskRunnerHandle::Get(), + std::move(callback))); } void DataCollectorImpl::GetTouchpadLibraryName(
diff --git a/chromeos/services/cros_healthd/private/mojom/cros_healthd_internal.mojom b/chromeos/services/cros_healthd/private/mojom/cros_healthd_internal.mojom index 333a6ad..0959aab 100644 --- a/chromeos/services/cros_healthd/private/mojom/cros_healthd_internal.mojom +++ b/chromeos/services/cros_healthd/private/mojom/cros_healthd_internal.mojom
@@ -46,7 +46,7 @@ [Extensible] enum ConnectionType { // For mojo backward compatibility. - [Default] kUnmappedEnumValue, + [Default] kUnmappedEnumField, // Internally connected input device. kInternal, // Known externally connected usb input device.
diff --git a/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.cc b/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.cc index 88a684c9..8cb9785 100644 --- a/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.cc +++ b/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/check.h" +#include "base/notreached.h" #include "base/threading/thread_task_runner_handle.h" #include "chromeos/ash/components/dbus/cros_healthd/cros_healthd_client.h" #include "chromeos/ash/components/dbus/cros_healthd/fake_cros_healthd_client.h" @@ -383,6 +384,13 @@ system_receiver_set_.Add(this, std::move(service)); } +void FakeCrosHealthd::SendChromiumDataCollector( + mojo::PendingRemote< + chromeos::cros_healthd::internal::mojom::ChromiumDataCollector> + remote) { + NOTIMPLEMENTED(); +} + void FakeCrosHealthd::GetServiceStatus(GetServiceStatusCallback callback) { auto response = mojom::ServiceStatus::New(); response->network_health_bound = network_health_remote_.is_bound();
diff --git a/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.h b/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.h index 508873b..2535401 100644 --- a/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.h +++ b/chromeos/services/cros_healthd/public/cpp/fake_cros_healthd.h
@@ -205,6 +205,10 @@ void GetSystemService(mojo::PendingReceiver< chromeos::cros_healthd::mojom::CrosHealthdSystemService> service) override; + void SendChromiumDataCollector( + mojo::PendingRemote< + chromeos::cros_healthd::internal::mojom::ChromiumDataCollector> + remote) override; // CrosHealthdDiagnosticsService overrides: void GetAvailableRoutines(GetAvailableRoutinesCallback callback) override;
diff --git a/chromeos/services/cros_healthd/public/mojom/BUILD.gn b/chromeos/services/cros_healthd/public/mojom/BUILD.gn index a56c1d5..1a86ab8 100644 --- a/chromeos/services/cros_healthd/public/mojom/BUILD.gn +++ b/chromeos/services/cros_healthd/public/mojom/BUILD.gn
@@ -16,6 +16,7 @@ ] public_deps = [ + "//chromeos/services/cros_healthd/private/mojom", "//chromeos/services/network_health/public/mojom", "//mojo/public/mojom/base", ]
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom index 33167b5..73bdcaaf 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom
@@ -10,6 +10,7 @@ module chromeos.cros_healthd.mojom; +import "chromeos/services/cros_healthd/private/mojom//cros_healthd_internal.mojom"; import "chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom"; import "chromeos/services/cros_healthd/public/mojom/cros_healthd_events.mojom"; import "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom"; @@ -22,7 +23,7 @@ // probe, diagnostics, or event services. Additionally, the browser can send // network-related implementations to the cros_healthd daemon. // -// NextMinVersion: 1, NextIndex: 6 +// NextMinVersion: 2, NextIndex: 7 interface CrosHealthdServiceFactory { // Returns a bound interface to the diagnostics service. GetDiagnosticsService@0(pending_receiver<CrosHealthdDiagnosticsService> service); @@ -43,6 +44,11 @@ // TODO(http://b/181133872): Move this service out of this interface // Returns a bound interface to the system service. GetSystemService@5(pending_receiver<CrosHealthdSystemService> service); + // Sends a NetworkDiagnosticsRoutines pending remote to the cros_healthd + // daemon. + [MinVersion=1] SendChromiumDataCollector@6( + pending_remote< + chromeos.cros_healthd.internal.mojom.ChromiumDataCollector> remote); }; // Diagnostics interface exposed by the cros_healthd daemon.
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom index 495d67f..9f784e4 100644 --- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom +++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
@@ -26,7 +26,7 @@ // An enumeration of each category of information that cros_healthd can report. // -// NextMinVersion: 1, NextIndex: 19 +// NextMinVersion: 1, NextIndex: 20 [Extensible] enum ProbeCategoryEnum { [Default] kUnknown = 16, @@ -48,6 +48,7 @@ kGraphics = 15, kDisplay = 17, kNetworkInterface = 18, + kInput = 19, // TODO(b/190459636): Rename it to kSystem after migration. kSystem2 = 0x10000, @@ -739,7 +740,7 @@ [Extensible] enum BootMode { [Default] kUnknown = 0, - // Boot with Chrome OS firmware. + // Boot with ChromeOS firmware. kCrosSecure = 1, // Boot with EFI kCrosEfi = 2, @@ -1312,6 +1313,70 @@ array<ThunderboltBusInterfaceInfo> thunderbolt_interfaces@1; }; +// Input result. +union InputResult { + // Valid InputInfo. + InputInfo input_info; + // The error that occurred attempting to retrieve the InputInfo. + ProbeError error; +}; + +// Input software and hardware information. +// +// NextMinVersion: 1, NextIndex: 2 +struct InputInfo { + // The touchpad library name used by the input stack. + string touchpad_library_name@0; + // The touchscreen devices. + array<TouchscreenDevice> touchscreen_devices@1; +}; + +// Data of a touch screen device. +// +// NextMinVersion: 1, NextIndex: 4 +struct TouchscreenDevice { + // The input device of this touchscreen. + InputDevice input_device@0; + // Number of touch points this device supports (0 if unknown). + int32 touch_points@1; + // True if the specified touchscreen device is stylus capable. + bool has_stylus@2; + // True if there is a garage/dock switch associated with the stylus. + bool has_stylus_garage_switch@3; +}; + +// Data of a input device. +// +// NextMinVersion: 1, NextIndex: 4 +struct InputDevice { + // Name of the device. + string name@0; + + // The connection type of the input device. + [Extensible] + enum ConnectionType { + // For mojo backward compatibility. + [Default] kUnmappedEnumField, + // Internally connected input device. + kInternal, + // Known externally connected usb input device. + kUSB, + // Known externally connected bluetooth input device. + kBluetooth, + // Device that may or may not be an external device. + kUnknown, + }; + + ConnectionType connection_type@1; + // The physical location(port) associated with the input device. This is + // (supposed to be) stable between reboots and hotplugs. However this may not + // always be set and will change when the device is connected via a different + // port. + string physical_location@2; + // If the device is enabled, and whether events should be dispatched to UI. + bool is_enabled@3; +}; + // A collection of all the device's telemetry information that cros_healthd is // capable of reporting. Note that every field in TelemetryInfo is nullable, and // the response for a particular ProbeTelemetryInfo request will only contain @@ -1320,7 +1385,7 @@ // attempt to fetch that information, and size zero if cros_healthd did attempt // to fetch that information, but was unable to. // -// NextMinVersion: 3, NextIndex: 19 +// NextMinVersion: 4, NextIndex: 20 struct TelemetryInfo { // Information about the device's main battery. Only present when kBattery was // included in the categories input to ProbeTelemetryInfo. @@ -1384,4 +1449,7 @@ // kNetworkInterface was included in the categories input to // ProbeTelemetryInfo. [MinVersion=2] NetworkInterfaceResult? network_interface_result@18; + // Information about the input software and hardware. Only present when + // kInput was included in the categories input to ProbeTelemetryInfo. + [MinVersion=3] InputResult? input_result@19; };
diff --git a/chromeos/services/libassistant/BUILD.gn b/chromeos/services/libassistant/BUILD.gn index 2ac4e0e..2f20d8d 100644 --- a/chromeos/services/libassistant/BUILD.gn +++ b/chromeos/services/libassistant/BUILD.gn
@@ -128,6 +128,7 @@ "//chromeos/ash/components/assistant:buildflags", "//chromeos/ash/resources", "//chromeos/assistant/internal", + "//chromeos/assistant/internal:buildflags", "//chromeos/assistant/internal:libassistant", "//chromeos/assistant/internal:libassistant_shared_headers", "//chromeos/assistant/internal:support",
diff --git a/chromeos/services/libassistant/chromium_api_delegate.cc b/chromeos/services/libassistant/chromium_api_delegate.cc index eb7affe..699c44a 100644 --- a/chromeos/services/libassistant/chromium_api_delegate.cc +++ b/chromeos/services/libassistant/chromium_api_delegate.cc
@@ -21,10 +21,12 @@ ChromiumApiDelegate::~ChromiumApiDelegate() = default; +#if !BUILDFLAG(IS_PREBUILT_LIBASSISTANT) assistant_client::HttpConnectionFactory* ChromiumApiDelegate::GetHttpConnectionFactory() { return &http_connection_factory_; } +#endif // !BUILDFLAG(IS_PREBUILT_LIBASSISTANT) } // namespace libassistant } // namespace chromeos
diff --git a/chromeos/services/libassistant/chromium_api_delegate.h b/chromeos/services/libassistant/chromium_api_delegate.h index a5e7ee2e..d0ddcb1 100644 --- a/chromeos/services/libassistant/chromium_api_delegate.h +++ b/chromeos/services/libassistant/chromium_api_delegate.h
@@ -21,6 +21,24 @@ class ChromiumHttpConnectionFactory; +// TODO(b/195985225): `ChromeOSApiDelegate` is not supported in the prebuilt +// library. +#if BUILDFLAG(IS_PREBUILT_LIBASSISTANT) +class ChromiumApiDelegate { + public: + explicit ChromiumApiDelegate( + std::unique_ptr<network::PendingSharedURLLoaderFactory> + pending_url_loader_factory); + + ChromiumApiDelegate(const ChromiumApiDelegate&) = delete; + ChromiumApiDelegate& operator=(const ChromiumApiDelegate&) = delete; + + ~ChromiumApiDelegate(); + + private: + ChromiumHttpConnectionFactory http_connection_factory_; +}; +#else class ChromiumApiDelegate : public assistant_client::ChromeOSApiDelegate { public: explicit ChromiumApiDelegate( @@ -40,6 +58,7 @@ private: ChromiumHttpConnectionFactory http_connection_factory_; }; +#endif // BUILDFLAG(IS_PREBUILT_LIBASSISTANT) } // namespace libassistant } // namespace chromeos
diff --git a/chromeos/services/libassistant/conversation_state_listener_impl.cc b/chromeos/services/libassistant/conversation_state_listener_impl.cc index d5c9b058..0f8daa18 100644 --- a/chromeos/services/libassistant/conversation_state_listener_impl.cc +++ b/chromeos/services/libassistant/conversation_state_listener_impl.cc
@@ -122,6 +122,11 @@ case Resolution::LONGFORM_KEEP_MIC_OPEN: NOTREACHED(); return; +#if BUILDFLAG(IS_PREBUILT_LIBASSISTANT) + case Resolution::BLUE_STEEL_ON_DEVICE_REJECTION: + NOTREACHED(); + return; +#endif // BUILDFLAG(IS_PREBUILT_LIBASSISTANT) } }
diff --git a/chromeos/services/libassistant/grpc/assistant_client_v1.cc b/chromeos/services/libassistant/grpc/assistant_client_v1.cc index 79d9f40..a757da8 100644 --- a/chromeos/services/libassistant/grpc/assistant_client_v1.cc +++ b/chromeos/services/libassistant/grpc/assistant_client_v1.cc
@@ -348,9 +348,11 @@ void AssistantClientV1::SetChromeOSApiDelegate( assistant_client::ChromeOSApiDelegate* delegate) { +#if !BUILDFLAG(IS_PREBUILT_LIBASSISTANT) assistant_manager_internal() ->GetFuchsiaApiHelperOrDie() ->SetChromeOSApiDelegate(delegate); +#endif // !BUILDFLAG(IS_PREBUILT_LIBASSISTANT) } bool AssistantClientV1::StartGrpcServices() {
diff --git a/chromeos/services/libassistant/service_controller.cc b/chromeos/services/libassistant/service_controller.cc index 6dab85a2..c05fc10d 100644 --- a/chromeos/services/libassistant/service_controller.cc +++ b/chromeos/services/libassistant/service_controller.cc
@@ -120,10 +120,7 @@ return; } - // Currently only V1 library is uploaded to DLC. - if (!chromeos::assistant::features::IsLibAssistantV2Enabled()) { - libassistant_factory_.LoadLibassistantLibraryFromDlc(config->dlc_path); - } + libassistant_factory_.LoadLibassistantLibraryFromDlc(config->dlc_path); auto assistant_manager = libassistant_factory_.CreateAssistantManager( ToLibassistantConfig(*config)); @@ -324,9 +321,9 @@ mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory_remote) { CreateChromiumApiDelegate(std::move(url_loader_factory_remote)); - if (!chromeos::assistant::features::IsLibAssistantV2Enabled()) { - assistant_client_->SetChromeOSApiDelegate(chromium_api_delegate_.get()); - } +#if !BUILDFLAG(IS_PREBUILT_LIBASSISTANT) + assistant_client_->SetChromeOSApiDelegate(chromium_api_delegate_.get()); +#endif // !BUILDFLAG(IS_PREBUILT_LIBASSISTANT) } void ServiceController::CreateChromiumApiDelegate(
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 6b73adc1..49995d2 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -631,10 +631,8 @@ } WebInputElement input_element = element_.DynamicTo<WebInputElement>(); - if (!input_element.IsNull()) { - DoFillFieldWithValue(value, input_element); - input_element.SetAutofillState(WebAutofillState::kAutofilled); - } + if (!input_element.IsNull()) + DoFillFieldWithValue(value, input_element, WebAutofillState::kAutofilled); } void AutofillAgent::PreviewFieldWithValue(FieldRendererId field_id, @@ -723,7 +721,7 @@ new_value = base::JoinString(parts, u","); } - DoFillFieldWithValue(new_value, input_element); + DoFillFieldWithValue(new_value, input_element, WebAutofillState::kNotFilled); } void AutofillAgent::FillPasswordSuggestion(const std::u16string& username, @@ -952,11 +950,12 @@ } void AutofillAgent::DoFillFieldWithValue(const std::u16string& value, - WebInputElement& node) { + WebInputElement& node, + WebAutofillState autofill_state) { DCHECK(IsOwnedByFrame(node, render_frame())); form_tracker_.set_ignore_control_changes(true); - node.SetAutofillValue(blink::WebString::FromUTF16(value)); + node.SetAutofillValue(blink::WebString::FromUTF16(value), autofill_state); password_autofill_agent_->UpdateStateForTextChange(node); form_tracker_.set_ignore_control_changes(false); } @@ -968,7 +967,6 @@ ClearPreviewedForm(); query_node_autofill_state_ = element_.GetAutofillState(); node.SetSuggestedValue(blink::WebString::FromUTF16(value)); - node.SetAutofillState(WebAutofillState::kPreviewed); form_util::PreviewSuggestion(node.SuggestedValue().Utf16(), node.Value().Utf16(), &node); previewed_elements_.push_back(node);
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h index 33ffacbf..4de7f06 100644 --- a/components/autofill/content/renderer/autofill_agent.h +++ b/components/autofill/content/renderer/autofill_agent.h
@@ -259,7 +259,8 @@ // Set |node| to display the given |value|. void DoFillFieldWithValue(const std::u16string& value, - blink::WebInputElement& node); + blink::WebInputElement& node, + blink::WebAutofillState autofill_state); // Set |node| to display the given |value| as a preview. The preview is // visible on screen to the user, but not visible to the page via the DOM or
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index cecb9429..43e16c95 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1192,7 +1192,8 @@ WebInputElement input_element = field->DynamicTo<WebInputElement>(); if (IsCheckableElement(input_element)) { - input_element.SetChecked(IsChecked(data.check_status), true); + input_element.SetChecked(IsChecked(data.check_status), true, + WebAutofillState::kAutofilled); } else { std::u16string value = data.value; if (IsTextInput(input_element) || IsMonthInput(input_element)) { @@ -1200,15 +1201,14 @@ // returns the default maxlength value. TruncateString(&value, input_element.MaxLength()); } - field->SetAutofillValue(blink::WebString::FromUTF16(value)); + field->SetAutofillValue(blink::WebString::FromUTF16(value), + WebAutofillState::kAutofilled); } // Setting the form might trigger JavaScript, which is capable of // destroying the frame. if (!field->GetDocument().GetFrame()) return; - field->SetAutofillState(WebAutofillState::kAutofilled); - if (is_initiating_node && ((IsTextInput(input_element) || IsMonthInput(input_element)) || IsTextAreaElement(*field))) { @@ -1240,10 +1240,8 @@ // returns the default maxlength value. input_element.SetSuggestedValue(blink::WebString::FromUTF16( data.value.substr(0, input_element.MaxLength()))); - input_element.SetAutofillState(WebAutofillState::kPreviewed); } else if (IsTextAreaElement(*field) || IsSelectElement(*field)) { field->SetSuggestedValue(blink::WebString::FromUTF16(data.value)); - field->SetAutofillState(WebAutofillState::kPreviewed); } if (is_initiating_node &&
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc index 0f15fe0..be8cf7d 100644 --- a/components/autofill/content/renderer/form_cache.cc +++ b/components/autofill/content/renderer/form_cache.cc
@@ -231,7 +231,7 @@ } void FormCache::ClearElement(WebFormControlElement& control_element, - const WebFormControlElement& element) { + const WebFormControlElement& trigger_element) { // Don't modify the value of disabled fields. if (!control_element.IsEnabled()) return; @@ -240,25 +240,30 @@ if (!control_element.IsAutofilled()) return; - if (control_element.AutofillSection() != element.AutofillSection()) + if (control_element.AutofillSection() != trigger_element.AutofillSection()) return; - control_element.SetAutofillState(WebAutofillState::kNotFilled); + if (!form_util::IsAutofillableElement(control_element)) { + NOTREACHED(); + return; + } WebInputElement web_input_element = control_element.DynamicTo<WebInputElement>(); if (form_util::IsTextInput(web_input_element) || form_util::IsMonthInput(web_input_element)) { - web_input_element.SetAutofillValue(blink::WebString()); + web_input_element.SetAutofillValue(blink::WebString(), + WebAutofillState::kNotFilled); // Clearing the value in the focused node (above) can cause the selection // to be lost. We force the selection range to restore the text cursor. - if (element == web_input_element) { + if (trigger_element == web_input_element) { size_t length = web_input_element.Value().length(); web_input_element.SetSelectionRange(length, length); } } else if (form_util::IsTextAreaElement(control_element)) { - control_element.SetAutofillValue(blink::WebString()); + control_element.SetAutofillValue(blink::WebString(), + WebAutofillState::kNotFilled); } else if (form_util::IsSelectElement(control_element)) { WebSelectElement select_element = control_element.To<WebSelectElement>(); auto initial_value_iter = initial_select_values_.find( @@ -266,18 +271,23 @@ if (initial_value_iter != initial_select_values_.end() && select_element.Value().Utf16() != initial_value_iter->second) { select_element.SetAutofillValue( - blink::WebString::FromUTF16(initial_value_iter->second)); + blink::WebString::FromUTF16(initial_value_iter->second), + blink::WebAutofillState::kNotFilled); select_element.SetUserHasEditedTheField(false); + } else { + select_element.SetAutofillState(WebAutofillState::kNotFilled); } - } else { + } else if (form_util::IsCheckableElement(web_input_element)) { WebInputElement input_element = control_element.To<WebInputElement>(); - DCHECK(form_util::IsCheckableElement(input_element)); auto checkable_element_it = initial_checked_state_.find( FieldRendererId(input_element.UniqueRendererFormControlId())); if (checkable_element_it != initial_checked_state_.end() && input_element.IsChecked() != checkable_element_it->second) { - input_element.SetChecked(checkable_element_it->second, true); + input_element.SetChecked(checkable_element_it->second, true, + WebAutofillState::kNotFilled); } + } else { + NOTREACHED(); } }
diff --git a/components/autofill/content/renderer/form_cache.h b/components/autofill/content/renderer/form_cache.h index a7a84e2..8f8ffd7b 100644 --- a/components/autofill/content/renderer/form_cache.h +++ b/components/autofill/content/renderer/form_cache.h
@@ -120,8 +120,10 @@ const std::vector<blink::WebFormControlElement>& control_elements); // Clears the value of the |control_element|. + // |trigger_element| is the element on which the user triggered a request + // to clear the form. void ClearElement(blink::WebFormControlElement& control_element, - const blink::WebFormControlElement& element); + const blink::WebFormControlElement& trigger_element); // Clears all entries from |initial_select_values_| and // |initial_checked_state_| whose keys not contained in |ids_to_retain|.
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 14d955a6..bcf21878 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -716,18 +716,12 @@ void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue( WebInputElement* element) { - if (!element->IsNull() && !element->SuggestedValue().IsEmpty()) { + if (!element->IsNull() && !element->SuggestedValue().IsEmpty()) element->SetAutofillValue(element->SuggestedValue()); - element->SetAutofillState(WebAutofillState::kAutofilled); - } } bool PasswordAutofillAgent::TextDidChangeInTextField( const WebInputElement& element) { - // TODO(crbug.com/415449): Do this through const WebInputElement. - WebInputElement mutable_element = element; // We need a non-const. - mutable_element.SetAutofillState(WebAutofillState::kNotFilled); - auto iter = web_input_to_password_info_.find(element); if (iter != web_input_to_password_info_.end()) { iter->second.password_was_edited_last = false; @@ -860,7 +854,6 @@ DCHECK(input); DCHECK(!input->IsNull()); input->SetAutofillValue(WebString::FromUTF16(credential)); - input->SetAutofillState(WebAutofillState::kAutofilled); const FieldRendererId input_id(input->UniqueRendererFormControlId()); field_data_manager_->UpdateFieldDataMap( input_id, credential, FieldPropertiesFlags::kAutofilledOnUserTrigger); @@ -903,14 +896,12 @@ username_autofill_state_ = username_element.GetAutofillState(); username_element.SetSuggestedValue(username); - username_element.SetAutofillState(WebAutofillState::kPreviewed); form_util::PreviewSuggestion(username_element.SuggestedValue().Utf16(), username_query_prefix_, &username_element); } if (!password_element.IsNull()) { password_autofill_state_ = password_element.GetAutofillState(); password_element.SetSuggestedValue(password); - password_element.SetAutofillState(WebAutofillState::kPreviewed); } return true; @@ -1499,12 +1490,11 @@ for (WebFormControlElement& element : elements) { if (element.IsNull()) continue; - element.SetSuggestedValue(blink::WebString()); // Don't clear the actual value of fields that the user has edited manually // (which changes the autofill state back to kNotFilled). if (element.GetAutofillState() == WebAutofillState::kAutofilled) element.SetValue(blink::WebString()); - element.SetAutofillState(WebAutofillState::kNotFilled); + element.SetSuggestedValue(blink::WebString()); } all_autofilled_elements_.clear(); @@ -2141,6 +2131,10 @@ if (cached_element == autofilled_elements_cache_.end()) continue; + // autofilled_elements_cache_ stores values filled at page load time and + // gets wiped when we observe a user gesture. During this time, the + // username/password fields can be in preview state and we restore this + // state if JavaScript modifies the field's value. const WebString& cached_value = cached_element->second; if (cached_value != element.SuggestedValue()) element.SetSuggestedValue(cached_value);
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index fcdc9dd..77fa8ac 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -574,7 +574,8 @@ bool prefilled_username_metrics_logged_ = false; - // Keeps autofilled values for the form elements. + // Keeps autofilled values for the form elements until a user gesture + // is observed. At that point, the map is cleared. std::map<FieldRendererId, blink::WebString> autofilled_elements_cache_; std::set<FieldRendererId> all_autofilled_elements_; // Keeps forms structure (amount of elements, element types etc).
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc index 36c39e3e..e780918 100644 --- a/components/autofill/content/renderer/password_generation_agent.cc +++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -308,7 +308,6 @@ // frame. if (!render_frame()) return; - password_element.SetAutofillState(WebAutofillState::kAutofilled); password_agent_->TrackAutofilledElement(password_element); // Advance focus to the next input field. We assume password fields in // an account creation form are always adjacent.
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 8819d68..7c9121e 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -388,7 +388,9 @@ sync_service && !sync_service_->IsSyncFeatureEnabled()); } +#if BUILDFLAG(IS_CHROMEOS_ASH) MigrateUserOptedInWalletSyncTransportIfNeeded(); +#endif } void PersonalDataManager::OnURLsDeleted( @@ -2261,6 +2263,7 @@ pending_offer_data_query_ != 0; } +#if BUILDFLAG(IS_CHROMEOS_ASH) void PersonalDataManager::MigrateUserOptedInWalletSyncTransportIfNeeded() { if (!sync_service_) return; @@ -2322,6 +2325,7 @@ prefs::SetUserOptedInWalletSyncTransport(pref_service_, primary_account_id, /*opted_in=*/true); } +#endif bool PersonalDataManager::IsSyncEnabledFor(syncer::ModelType model_type) { return sync_service_ != nullptr && sync_service_->CanSyncFeatureStart() &&
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index ec5b22a..b5e1fe7e 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -781,9 +781,11 @@ // Returns if there are any pending queries to the web database. bool HasPendingQueries(); +#if BUILDFLAG(IS_CHROMEOS_ASH) // Migrates the user opted in to wallet sync transport. This is needed while // migrating from using email to Gaia ID as th account identifier. void MigrateUserOptedInWalletSyncTransportIfNeeded(); +#endif // Returns true if the sync is enabled for |model_type|. bool IsSyncEnabledFor(syncer::ModelType model_type);
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index b954f63..c40f661d 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -576,21 +576,18 @@ void TearDown() override { TearDownTest(); } }; +#if BUILDFLAG(IS_CHROMEOS_ASH) class PersonalDataManagerMigrationTest : public PersonalDataManagerHelper, public testing::Test { public: PersonalDataManagerMigrationTest() - : PersonalDataManagerHelper( -#if BUILDFLAG(IS_CHROMEOS_ASH) - { ::switches::kAccountIdMigration } -#endif - ) { - } + : PersonalDataManagerHelper({::switches::kAccountIdMigration}) {} protected: void SetUp() override { SetUpTest(); } void TearDown() override { TearDownTest(); } }; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) class PersonalDataManagerMockTest : public PersonalDataManagerTestBase, public testing::Test { @@ -6687,9 +6684,7 @@ EXPECT_TRUE(personal_data_->IsNewProfileImportBlockedForDomain(second_url)); } -// On mobile, no dedicated opt-in is required for WalletSyncTransport - the -// user is always considered opted-in and thus this test doesn't make sense. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PersonalDataManagerMigrationTest, MigrateUserOptedInWalletSyncTransportIfNeeded) { ASSERT_EQ( @@ -6708,7 +6703,7 @@ EXPECT_TRUE(::autofill::prefs::IsUserOptedInWalletSyncTransport( prefs_.get(), sync_service_.GetAccountInfo().account_id)); } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +#endif // BUILDFLAG(IS_CHROMEOS_ASH) #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
diff --git a/components/autofill_assistant/browser/web/css_element_finder.cc b/components/autofill_assistant/browser/web/css_element_finder.cc index b8024754..2a1fe69 100644 --- a/components/autofill_assistant/browser/web/css_element_finder.cc +++ b/components/autofill_assistant/browser/web/css_element_finder.cc
@@ -152,16 +152,11 @@ return; } - if (selector_.proto.has_semantic_information()) { - devtools_client_->GetDOM()->DescribeNode( - dom::DescribeNodeParams::Builder().SetObjectId(object_id).Build(), - current_frame_id_, - base::BindOnce(&CssElementFinder::OnDescribeNodeForId, - weak_ptr_factory_.GetWeakPtr(), object_id)); - return; - } - - BuildAndSendResult(object_id); + devtools_client_->GetDOM()->DescribeNode( + dom::DescribeNodeParams::Builder().SetObjectId(object_id).Build(), + current_frame_id_, + base::BindOnce(&CssElementFinder::OnDescribeNodeForId, + weak_ptr_factory_.GetWeakPtr(), object_id)); } void CssElementFinder::OnDescribeNodeForId( @@ -178,6 +173,7 @@ ElementFinderResult result; result.SetRenderFrameHost(current_frame_); result.SetObjectId(object_id); + result.SetBackendNodeId(backend_node_id_); result.SetNodeFrameId(current_frame_id_); result.SetFrameStack(frame_stack_);
diff --git a/components/autofill_assistant/browser/web/element.h b/components/autofill_assistant/browser/web/element.h index 04aef40..fa360ab 100644 --- a/components/autofill_assistant/browser/web/element.h +++ b/components/autofill_assistant/browser/web/element.h
@@ -11,6 +11,7 @@ #include "content/public/browser/global_routing_id.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace autofill_assistant { @@ -25,6 +26,9 @@ // context of the frame. Might be empty if no frame id needs to be // specified. std::string node_frame_id; + + // The node id of this object. This is only available for nodes. + absl::optional<int> backend_node_id; }; // DomObjectFrameStack contains all data required to use an object including
diff --git a/components/autofill_assistant/browser/web/element_finder_result.h b/components/autofill_assistant/browser/web/element_finder_result.h index ca030e6..4bdf5cd 100644 --- a/components/autofill_assistant/browser/web/element_finder_result.h +++ b/components/autofill_assistant/browser/web/element_finder_result.h
@@ -44,6 +44,10 @@ return dom_object_.object_data.object_id; } + absl::optional<int> backend_node_id() const { + return dom_object_.object_data.backend_node_id; + } + const std::string& node_frame_id() const { return dom_object_.object_data.node_frame_id; } @@ -67,6 +71,10 @@ dom_object_.object_data.object_id = object_id; } + void SetBackendNodeId(absl::optional<int> backend_node_id) { + dom_object_.object_data.backend_node_id = backend_node_id; + } + void SetNodeFrameId(const std::string& node_frame_id) { dom_object_.object_data.node_frame_id = node_frame_id; }
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder.cc b/components/autofill_assistant/browser/web/semantic_element_finder.cc index 53d36541f5..8ba3af6 100644 --- a/components/autofill_assistant/browser/web/semantic_element_finder.cc +++ b/components/autofill_assistant/browser/web/semantic_element_finder.cc
@@ -75,7 +75,8 @@ void SemanticElementFinder::ResultFound( content::RenderFrameHost* render_frame_host, - const std::string& object_id) { + const std::string& object_id, + int backend_node_id) { if (!callback_) { return; } @@ -83,6 +84,7 @@ ElementFinderResult result; result.SetRenderFrameHost(render_frame_host); result.SetObjectId(object_id); + result.SetBackendNodeId(backend_node_id); SendResult(OkClientStatus(), result); } @@ -225,16 +227,16 @@ /* current_frame_id= */ std::string(), base::BindOnce(&SemanticElementFinder::OnResolveNodeForAnnotateDom, weak_ptr_factory_.GetWeakPtr(), - semantic_node_results_[0].host_id())); + semantic_node_results_[0])); } void SemanticElementFinder::OnResolveNodeForAnnotateDom( - content::GlobalRenderFrameHostId host_id, + GlobalBackendNodeId node, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<dom::ResolveNodeResult> result) { if (result && result->GetObject() && result->GetObject()->HasObjectId()) { - ResultFound(content::RenderFrameHost::FromID(host_id), - result->GetObject()->GetObjectId()); + ResultFound(content::RenderFrameHost::FromID(node.host_id()), + result->GetObject()->GetObjectId(), node.backend_node_id()); return; } SendResult(ClientStatus(ELEMENT_RESOLUTION_FAILED),
diff --git a/components/autofill_assistant/browser/web/semantic_element_finder.h b/components/autofill_assistant/browser/web/semantic_element_finder.h index e68cbe5..00a68543 100644 --- a/components/autofill_assistant/browser/web/semantic_element_finder.h +++ b/components/autofill_assistant/browser/web/semantic_element_finder.h
@@ -54,10 +54,11 @@ // Returns the given status and no element. This expects an error status. void GiveUpWithError(const ClientStatus& status); - // Builds a result from the |render_frame_host| and the |object_id| and - // returns it withan ok status. + // Builds a result from the |render_frame_host|, the |object_id| and the + // |backend_node_id| returns it withan ok status. void ResultFound(content::RenderFrameHost* render_frame_host, - const std::string& object_id); + const std::string& object_id, + int backend_node_id); // Call |callback_| with the |status| and |result|. void SendResult(const ClientStatus& status, @@ -81,7 +82,7 @@ const std::vector<std::vector<GlobalBackendNodeId>>& all_nodes); void OnResolveNodeForAnnotateDom( - content::GlobalRenderFrameHostId host_id, + GlobalBackendNodeId node, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<dom::ResolveNodeResult> result);
diff --git a/components/autofill_assistant/browser/web/web_controller.cc b/components/autofill_assistant/browser/web/web_controller.cc index 953d9bc1..09b6b5e 100644 --- a/components/autofill_assistant/browser/web/web_controller.cc +++ b/components/autofill_assistant/browser/web/web_controller.cc
@@ -1000,11 +1000,26 @@ ContentAutofillDriver* driver, const autofill::FormData&, const autofill::FormFieldData&)> callback) { - GetBackendNodeId( - element, - base::BindOnce(&WebController::OnGetBackendNodeIdForFormAndFieldData, - weak_ptr_factory_.GetWeakPtr(), element, - std::move(callback))); + if (!element.backend_node_id()) { + std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__), nullptr, + autofill::FormData(), autofill::FormFieldData()); + return; + } + + ContentAutofillDriver* driver = + ContentAutofillDriver::GetForRenderFrameHost(element.render_frame_host()); + if (driver == nullptr) { + DVLOG(1) << __func__ << " Failed to get the autofill driver."; + std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__), nullptr, + autofill::FormData(), autofill::FormFieldData()); + return; + } + + driver->GetAutofillAgent()->GetElementFormAndFieldDataForDevToolsNodeId( + *element.backend_node_id(), + base::BindOnce(&WebController::OnGetFormAndFieldData, + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + driver)); } void WebController::GetBackendNodeId( @@ -1034,35 +1049,6 @@ result->GetNode()->GetBackendNodeId()); } -void WebController::OnGetBackendNodeIdForFormAndFieldData( - const ElementFinderResult& element, - base::OnceCallback<void(const ClientStatus&, - ContentAutofillDriver* driver, - const autofill::FormData&, - const autofill::FormFieldData&)> callback, - const ClientStatus& node_status, - const int backend_node_id) { - if (!node_status.ok()) { - std::move(callback).Run(node_status, nullptr, autofill::FormData(), - autofill::FormFieldData()); - return; - } - - ContentAutofillDriver* driver = - ContentAutofillDriver::GetForRenderFrameHost(element.render_frame_host()); - if (driver == nullptr) { - DVLOG(1) << __func__ << " Failed to get the autofill driver."; - std::move(callback).Run(UnexpectedErrorStatus(__FILE__, __LINE__), nullptr, - autofill::FormData(), autofill::FormFieldData()); - return; - } - - driver->GetAutofillAgent()->GetElementFormAndFieldDataForDevToolsNodeId( - backend_node_id, base::BindOnce(&WebController::OnGetFormAndFieldData, - weak_ptr_factory_.GetWeakPtr(), - std::move(callback), driver)); -} - void WebController::OnGetFormAndFieldData( base::OnceCallback<void(const ClientStatus&, ContentAutofillDriver* driver,
diff --git a/components/autofill_assistant/browser/web/web_controller.h b/components/autofill_assistant/browser/web/web_controller.h index 921cd8b1..3427d02f 100644 --- a/components/autofill_assistant/browser/web/web_controller.h +++ b/components/autofill_assistant/browser/web/web_controller.h
@@ -464,14 +464,6 @@ base::OnceCallback<void(const ClientStatus&, int)> callback, const DevtoolsClient::ReplyStatus& reply_status, std::unique_ptr<dom::DescribeNodeResult> result); - void OnGetBackendNodeIdForFormAndFieldData( - const ElementFinderResult& element, - base::OnceCallback<void(const ClientStatus&, - autofill::ContentAutofillDriver* driver, - const autofill::FormData&, - const autofill::FormFieldData&)> callback, - const ClientStatus& node_status, - int backend_node_id); void OnGetFormAndFieldData( base::OnceCallback<void(const ClientStatus&, autofill::ContentAutofillDriver* driver,
diff --git a/components/gcm_driver/gcm_profile_service.cc b/components/gcm_driver/gcm_profile_service.cc index 6b6bed3..27c3ea2b 100644 --- a/components/gcm_driver/gcm_profile_service.cc +++ b/components/gcm_driver/gcm_profile_service.cc
@@ -157,11 +157,17 @@ scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) : identity_manager_(identity_manager), url_loader_factory_(std::move(url_loader_factory)) { +#if BUILDFLAG(IS_CHROMEOS_ASH) signin::IdentityManager::AccountIdMigrationState id_migration = identity_manager_->GetAccountIdMigrationState(); bool remove_account_mappings_with_email_key = (id_migration == signin::IdentityManager::MIGRATION_IN_PROGRESS) || (id_migration == signin::IdentityManager::MIGRATION_DONE); +#else + // Migration is done on non-ChromeOS platforms. + bool remove_account_mappings_with_email_key = false; +#endif + driver_ = CreateGCMDriverDesktop( std::move(gcm_client_factory), prefs, path.Append(gcm_driver::kGCMStoreDirname),
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 188793a..7864061 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -314,7 +314,7 @@ delegate_->DBLoaded(); typed_url_sync_bridge_ = std::make_unique<TypedURLSyncBridge>( - this, db_.get(), + this, db_ ? db_->GetTypedURLMetadataDB() : nullptr, std::make_unique<ClientTagBasedModelTypeProcessor>( syncer::TYPED_URLS, /*dump_stack=*/base::RepeatingClosure())); typed_url_sync_bridge_->Init();
diff --git a/components/history/core/browser/history_database.cc b/components/history/core/browser/history_database.cc index 4f6e728..5cf6b84 100644 --- a/components/history/core/browser/history_database.cc +++ b/components/history/core/browser/history_database.cc
@@ -92,7 +92,8 @@ // Set the cache size. The page size, plus a little extra, times this // value, tells us how much memory the cache will use maximum. // 1000 * 4kB = 4MB - .cache_size = 1000}) {} + .cache_size = 1000}), + typed_url_metadata_db_(&db_, &meta_table_) {} HistoryDatabase::~HistoryDatabase() = default; @@ -122,7 +123,7 @@ return LogInitFailure(InitStep::META_TABLE_INIT); if (!CreateURLTable(false) || !InitVisitTable() || !InitKeywordSearchTermsTable() || !InitDownloadTable() || - !InitSegmentTables() || !InitTypedURLMetadataTable() || + !InitSegmentTables() || !typed_url_metadata_db_.Init() || !InitVisitAnnotationsTables()) { return LogInitFailure(InitStep::CREATE_TABLES); } @@ -374,12 +375,12 @@ cached_early_expiration_threshold_ = threshold; } -sql::Database& HistoryDatabase::GetDB() { - return db_; +TypedURLSyncMetadataDatabase* HistoryDatabase::GetTypedURLMetadataDB() { + return &typed_url_metadata_db_; } -sql::MetaTable& HistoryDatabase::GetMetaTable() { - return meta_table_; +sql::Database& HistoryDatabase::GetDB() { + return db_; } // Migration ------------------------------------------------------------------- @@ -593,7 +594,7 @@ std::vector<URLID> visited_url_rowids_sorted; if (!GetAllVisitedURLRowidsForMigrationToVersion40( &visited_url_rowids_sorted) || - !CleanTypedURLOrphanedMetadataForMigrationToVersion40( + !typed_url_metadata_db_.CleanOrphanedMetadataForMigrationToVersion40( visited_url_rowids_sorted)) { return LogMigrationFailure(40); }
diff --git a/components/history/core/browser/history_database.h b/components/history/core/browser/history_database.h index f34bf6f..fd168499 100644 --- a/components/history/core/browser/history_database.h +++ b/components/history/core/browser/history_database.h
@@ -17,6 +17,7 @@ #include "components/history/core/browser/visit_annotations_database.h" #include "components/history/core/browser/visit_database.h" #include "components/history/core/browser/visitsegment_database.h" +#include "components/sync/model/model_type_store_base.h" #include "sql/database.h" #include "sql/init_status.h" #include "sql/meta_table.h" @@ -46,7 +47,6 @@ public AndroidURLsDatabase, public AndroidCacheDatabase, #endif - public TypedURLSyncMetadataDatabase, public URLDatabase, public VisitDatabase, public VisitAnnotationsDatabase, @@ -156,6 +156,11 @@ virtual base::Time GetEarlyExpirationThreshold(); virtual void UpdateEarlyExpirationThreshold(base::Time threshold); + // Sync metadata storage ---------------------------------------------------- + + // Returns the sub-database used for storing Sync metadata for Typed URLs. + TypedURLSyncMetadataDatabase* GetTypedURLMetadataDB(); + private: #if BUILDFLAG(IS_ANDROID) // AndroidProviderBackend uses the `db_`. @@ -164,13 +169,10 @@ #endif friend class ::InMemoryURLIndexTest; - // Overridden from URLDatabase, DownloadDatabase, VisitDatabase, - // VisitSegmentDatabase and TypedURLSyncMetadataDatabase. + // Overridden from URLDatabase, DownloadDatabase, VisitDatabase, and + // VisitSegmentDatabase. sql::Database& GetDB() override; - // Overridden from TypedURLSyncMetadataDatabase. - sql::MetaTable& GetMetaTable() override; - // Migration ----------------------------------------------------------------- // Makes sure the version is up to date, updating if necessary. If the @@ -192,6 +194,12 @@ sql::Database db_; sql::MetaTable meta_table_; + // Most of the sub-DBs (URLDatabase etc.) are integrated into HistoryDatabase + // via inheritance. However, that can lead to "diamond inheritance" issues + // when multiple of these base classes define the same methods. Therefore the + // Sync metadata DB is integrated via composition instead. + TypedURLSyncMetadataDatabase typed_url_metadata_db_; + base::Time cached_early_expiration_threshold_; };
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc index d6d9d2a..99798af6 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
@@ -344,10 +344,10 @@ ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); fake_history_backend_->Init( false, TestHistoryDatabaseParamsForPath(test_dir_.GetPath())); - std::unique_ptr<TypedURLSyncBridge> bridge = - std::make_unique<TypedURLSyncBridge>( - fake_history_backend_.get(), fake_history_backend_->db(), - mock_processor_.CreateForwardingProcessor()); + auto bridge = std::make_unique<TypedURLSyncBridge>( + fake_history_backend_.get(), + fake_history_backend_->db()->GetTypedURLMetadataDB(), + mock_processor_.CreateForwardingProcessor()); typed_url_sync_bridge_ = bridge.get(); typed_url_sync_bridge_->Init(); typed_url_sync_bridge_->history_backend_observation_.Reset();
diff --git a/components/history/core/browser/sync/typed_url_sync_metadata_database.cc b/components/history/core/browser/sync/typed_url_sync_metadata_database.cc index ecc1efc6..2207516 100644 --- a/components/history/core/browser/sync/typed_url_sync_metadata_database.cc +++ b/components/history/core/browser/sync/typed_url_sync_metadata_database.cc
@@ -32,10 +32,25 @@ // value Serialize sync EntityMetadata, which is for tracking sync // state of each typed url. -TypedURLSyncMetadataDatabase::TypedURLSyncMetadataDatabase() = default; +TypedURLSyncMetadataDatabase::TypedURLSyncMetadataDatabase( + sql::Database* db, + sql::MetaTable* meta_table) + : db_(db), meta_table_(meta_table) {} TypedURLSyncMetadataDatabase::~TypedURLSyncMetadataDatabase() = default; +bool TypedURLSyncMetadataDatabase::Init() { + if (!db_->DoesTableExist("typed_url_sync_metadata")) { + if (!db_->Execute("CREATE TABLE typed_url_sync_metadata (" + "storage_key INTEGER PRIMARY KEY NOT NULL," + "value BLOB)")) { + NOTREACHED(); + return false; + } + } + return true; +} + bool TypedURLSyncMetadataDatabase::GetAllSyncMetadata( syncer::MetadataBatch* metadata_batch) { DCHECK(metadata_batch); @@ -59,9 +74,9 @@ DCHECK_EQ(model_type, syncer::TYPED_URLS) << "Only the TYPED_URLS model type is supported"; - sql::Statement s(GetDB().GetUniqueStatement( - "INSERT OR REPLACE INTO typed_url_sync_metadata " - "(storage_key, value) VALUES(?, ?)")); + sql::Statement s( + db_->GetUniqueStatement("INSERT OR REPLACE INTO typed_url_sync_metadata " + "(storage_key, value) VALUES(?, ?)")); s.BindInt64(0, StorageKeyToURLID(storage_key)); s.BindString(1, metadata.SerializeAsString()); @@ -74,7 +89,7 @@ DCHECK_EQ(model_type, syncer::TYPED_URLS) << "Only the TYPED_URLS model type is supported"; - sql::Statement s(GetDB().GetUniqueStatement( + sql::Statement s(db_->GetUniqueStatement( "DELETE FROM typed_url_sync_metadata WHERE storage_key=?")); s.BindInt64(0, StorageKeyToURLID(storage_key)); @@ -86,18 +101,18 @@ const sync_pb::ModelTypeState& model_type_state) { DCHECK_EQ(model_type, syncer::TYPED_URLS) << "Only the TYPED_URLS model type is supported"; - DCHECK_GT(GetMetaTable().GetVersionNumber(), 0); + DCHECK_GT(meta_table_->GetVersionNumber(), 0); std::string serialized_state = model_type_state.SerializeAsString(); - return GetMetaTable().SetValue(kTypedURLModelTypeStateKey, serialized_state); + return meta_table_->SetValue(kTypedURLModelTypeStateKey, serialized_state); } bool TypedURLSyncMetadataDatabase::ClearModelTypeState( syncer::ModelType model_type) { DCHECK_EQ(model_type, syncer::TYPED_URLS) << "Only the TYPED_URLS model type is supported"; - DCHECK_GT(GetMetaTable().GetVersionNumber(), 0); - return GetMetaTable().DeleteKey(kTypedURLModelTypeStateKey); + DCHECK_GT(meta_table_->GetVersionNumber(), 0); + return meta_table_->DeleteKey(kTypedURLModelTypeStateKey); } // static @@ -112,26 +127,13 @@ return storage_key_int; } -bool TypedURLSyncMetadataDatabase::InitTypedURLMetadataTable() { - if (!GetDB().DoesTableExist("typed_url_sync_metadata")) { - if (!GetDB().Execute("CREATE TABLE typed_url_sync_metadata (" - "storage_key INTEGER PRIMARY KEY NOT NULL," - "value BLOB)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool TypedURLSyncMetadataDatabase:: - CleanTypedURLOrphanedMetadataForMigrationToVersion40( - const std::vector<URLID>& sorted_valid_rowids) { +bool TypedURLSyncMetadataDatabase::CleanOrphanedMetadataForMigrationToVersion40( + const std::vector<URLID>& sorted_valid_rowids) { DCHECK(base::ranges::is_sorted(sorted_valid_rowids)); std::vector<URLID> invalid_metadata_rowids; auto valid_rowids_iter = sorted_valid_rowids.begin(); - sql::Statement sorted_metadata_rowids(GetDB().GetUniqueStatement( + sql::Statement sorted_metadata_rowids(db_->GetUniqueStatement( "SELECT storage_key FROM typed_url_sync_metadata ORDER BY storage_key")); while (sorted_metadata_rowids.Step()) { URLID metadata_rowid = sorted_metadata_rowids.ColumnInt64(0); @@ -155,7 +157,7 @@ } for (const URLID& rowid : invalid_metadata_rowids) { - sql::Statement del(GetDB().GetCachedStatement( + sql::Statement del(db_->GetCachedStatement( SQL_FROM_HERE, "DELETE FROM typed_url_sync_metadata WHERE storage_key=?")); del.BindInt64(0, rowid); @@ -170,7 +172,7 @@ bool TypedURLSyncMetadataDatabase::GetAllSyncEntityMetadata( syncer::MetadataBatch* metadata_batch) { DCHECK(metadata_batch); - sql::Statement s(GetDB().GetUniqueStatement( + sql::Statement s(db_->GetUniqueStatement( "SELECT storage_key, value FROM typed_url_sync_metadata")); while (s.Step()) { @@ -191,9 +193,9 @@ bool TypedURLSyncMetadataDatabase::GetModelTypeState( sync_pb::ModelTypeState* state) { - DCHECK_GT(GetMetaTable().GetVersionNumber(), 0); + DCHECK_GT(meta_table_->GetVersionNumber(), 0); std::string serialized_state; - if (!GetMetaTable().GetValue(kTypedURLModelTypeStateKey, &serialized_state)) { + if (!meta_table_->GetValue(kTypedURLModelTypeStateKey, &serialized_state)) { return true; }
diff --git a/components/history/core/browser/sync/typed_url_sync_metadata_database.h b/components/history/core/browser/sync/typed_url_sync_metadata_database.h index b20fd6c8..22015134 100644 --- a/components/history/core/browser/sync/typed_url_sync_metadata_database.h +++ b/components/history/core/browser/sync/typed_url_sync_metadata_database.h
@@ -29,9 +29,8 @@ // datatype. class TypedURLSyncMetadataDatabase : public syncer::SyncMetadataStore { public: - // Must call InitTypedURLMetadataTable() before using to make sure the - // database is initialized. - TypedURLSyncMetadataDatabase(); + // Must call Init() before using to make sure the database is initialized. + TypedURLSyncMetadataDatabase(sql::Database* db, sql::MetaTable* meta_table); TypedURLSyncMetadataDatabase(const TypedURLSyncMetadataDatabase&) = delete; TypedURLSyncMetadataDatabase& operator=(const TypedURLSyncMetadataDatabase&) = @@ -39,6 +38,10 @@ ~TypedURLSyncMetadataDatabase() override; + // Makes sure the tables and indices are properly set up. Must be called + // before anything else. + bool Init(); + // Read all the stored metadata for typed URL and fill `metadata_batch` // with it. bool GetAllSyncMetadata(syncer::MetadataBatch* metadata_batch); @@ -56,24 +59,11 @@ static URLID StorageKeyToURLID(const std::string& storage_key); - protected: - // Called by the derived classes on initialization to make sure the tables - // and indices are properly set up. Must be called before anything else. - bool InitTypedURLMetadataTable(); - - // Returns the database for the functions in this interface. - virtual sql::Database& GetDB() = 0; - - // Returns MetaTable, so this sync can store ModelTypeState in MetaTable. - // Check if GetMetaTable().GetVersionNumber() is greater than 0 to make sure - // MetaTable is initialed. - virtual sql::MetaTable& GetMetaTable() = 0; - // Cleans up orphaned metadata for typed URLs, i.e. deletes all metadata // entries for rowids not present in `sorted_valid_rowids` (which must be // sorted in ascending order). Returns true if the clean up finishes without // any DB error. - bool CleanTypedURLOrphanedMetadataForMigrationToVersion40( + bool CleanOrphanedMetadataForMigrationToVersion40( const std::vector<URLID>& sorted_valid_rowids); private: @@ -83,6 +73,9 @@ // Read sync_pb::ModelTypeState for typed URL and fill `state` with it. bool GetModelTypeState(sync_pb::ModelTypeState* state); + + sql::Database* const db_; + sql::MetaTable* const meta_table_; }; } // namespace history
diff --git a/components/history/core/browser/sync/typed_url_sync_metadata_database_unittest.cc b/components/history/core/browser/sync/typed_url_sync_metadata_database_unittest.cc index f491974..41b91e65 100644 --- a/components/history/core/browser/sync/typed_url_sync_metadata_database_unittest.cc +++ b/components/history/core/browser/sync/typed_url_sync_metadata_database_unittest.cc
@@ -32,10 +32,9 @@ } // namespace -class TypedURLSyncMetadataDatabaseTest : public testing::Test, - public TypedURLSyncMetadataDatabase { +class TypedURLSyncMetadataDatabaseTest : public testing::Test { public: - TypedURLSyncMetadataDatabaseTest() = default; + TypedURLSyncMetadataDatabaseTest() : sync_metadata_db_(&db_, &meta_table_) {} TypedURLSyncMetadataDatabaseTest(const TypedURLSyncMetadataDatabaseTest&) = delete; @@ -45,8 +44,6 @@ ~TypedURLSyncMetadataDatabaseTest() override = default; protected: - sql::Database& GetDB() override { return db_; } - void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); base::FilePath db_file = @@ -55,22 +52,22 @@ EXPECT_TRUE(db_.Open(db_file)); // Initialize the tables for this test. - InitTypedURLMetadataTable(); + sync_metadata_db_.Init(); - GetMetaTable().Init(&db_, 1, 1); + meta_table_.Init(&db_, 1, 1); } void TearDown() override { db_.Close(); } - sql::MetaTable& GetMetaTable() override { return meta_table_; } - base::ScopedTempDir temp_dir_; sql::Database db_; sql::MetaTable meta_table_; + + TypedURLSyncMetadataDatabase sync_metadata_db_; }; TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLNoMetadata) { MetadataBatch metadata_batch; - EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_TRUE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); EXPECT_EQ(0u, metadata_batch.TakeAllMetadata().size()); EXPECT_EQ(ModelTypeState().SerializeAsString(), metadata_batch.GetModelTypeState().SerializeAsString()); @@ -82,18 +79,21 @@ std::string storage_key2 = IntToStorageKey(2); metadata.set_sequence_number(1); - EXPECT_TRUE(UpdateSyncMetadata(syncer::TYPED_URLS, storage_key, metadata)); + EXPECT_TRUE(sync_metadata_db_.UpdateSyncMetadata(syncer::TYPED_URLS, + storage_key, metadata)); ModelTypeState model_type_state; model_type_state.set_initial_sync_done(true); - EXPECT_TRUE(UpdateModelTypeState(syncer::TYPED_URLS, model_type_state)); + EXPECT_TRUE(sync_metadata_db_.UpdateModelTypeState(syncer::TYPED_URLS, + model_type_state)); metadata.set_sequence_number(2); - EXPECT_TRUE(UpdateSyncMetadata(syncer::TYPED_URLS, storage_key2, metadata)); + EXPECT_TRUE(sync_metadata_db_.UpdateSyncMetadata(syncer::TYPED_URLS, + storage_key2, metadata)); MetadataBatch metadata_batch; - EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_TRUE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); EXPECT_TRUE(metadata_batch.GetModelTypeState().initial_sync_done()); @@ -105,9 +105,10 @@ // Now check that a model type state update replaces the old value model_type_state.set_initial_sync_done(false); - EXPECT_TRUE(UpdateModelTypeState(syncer::TYPED_URLS, model_type_state)); + EXPECT_TRUE(sync_metadata_db_.UpdateModelTypeState(syncer::TYPED_URLS, + model_type_state)); - EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_TRUE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); EXPECT_FALSE(metadata_batch.GetModelTypeState().initial_sync_done()); } @@ -122,40 +123,43 @@ metadata.set_client_tag_hash("client_hash"); // Write the data into the store. - EXPECT_TRUE(UpdateSyncMetadata(syncer::TYPED_URLS, storage_key, metadata)); - EXPECT_TRUE(UpdateModelTypeState(syncer::TYPED_URLS, model_type_state)); + EXPECT_TRUE(sync_metadata_db_.UpdateSyncMetadata(syncer::TYPED_URLS, + storage_key, metadata)); + EXPECT_TRUE(sync_metadata_db_.UpdateModelTypeState(syncer::TYPED_URLS, + model_type_state)); // Delete the data we just wrote. - EXPECT_TRUE(ClearSyncMetadata(syncer::TYPED_URLS, storage_key)); + EXPECT_TRUE( + sync_metadata_db_.ClearSyncMetadata(syncer::TYPED_URLS, storage_key)); // It shouldn't be there any more. - EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_TRUE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata(); EXPECT_EQ(metadata_records.size(), 0u); // Now delete the model type state. - EXPECT_TRUE(ClearModelTypeState(syncer::TYPED_URLS)); - EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_TRUE(sync_metadata_db_.ClearModelTypeState(syncer::TYPED_URLS)); + EXPECT_TRUE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); EXPECT_EQ(ModelTypeState().SerializeAsString(), metadata_batch.GetModelTypeState().SerializeAsString()); } TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLCorruptSyncMetadata) { MetadataBatch metadata_batch; - sql::Statement s(GetDB().GetUniqueStatement( - "INSERT OR REPLACE INTO typed_url_sync_metadata " - "(storage_key, value) VALUES(?, ?)")); + sql::Statement s( + db_.GetUniqueStatement("INSERT OR REPLACE INTO typed_url_sync_metadata " + "(storage_key, value) VALUES(?, ?)")); s.BindInt64(0, 1); s.BindString(1, "unparseable"); EXPECT_TRUE(s.Run()); - EXPECT_FALSE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_FALSE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); } TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLCorruptModelTypeState) { MetadataBatch metadata_batch; - GetMetaTable().SetValue("typed_url_model_type_state", "unparseable"); + meta_table_.SetValue("typed_url_model_type_state", "unparseable"); - EXPECT_FALSE(GetAllSyncMetadata(&metadata_batch)); + EXPECT_FALSE(sync_metadata_db_.GetAllSyncMetadata(&metadata_batch)); } } // namespace history
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 55d8443..1386b43 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -755,7 +755,7 @@ sources += [ "capabilities_service_impl_unittest.cc", "http_credentials_cleaner_unittest.cc", - "password_scripts_fetcher_impl_unittests.cc", + "password_scripts_fetcher_impl_unittest.cc", "saved_passwords_capabilities_fetcher_unittest.cc", ] }
diff --git a/components/password_manager/core/browser/password_scripts_fetcher_impl.cc b/components/password_manager/core/browser/password_scripts_fetcher_impl.cc index f3a88f3a..fa13330 100644 --- a/components/password_manager/core/browser/password_scripts_fetcher_impl.cc +++ b/components/password_manager/core/browser/password_scripts_fetcher_impl.cc
@@ -103,17 +103,21 @@ kDefaultChangePasswordScriptsListUrl}; PasswordScriptsFetcherImpl::PasswordScriptsFetcherImpl( + bool is_supervised_user, const base::Version& version, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : PasswordScriptsFetcherImpl(version, + : PasswordScriptsFetcherImpl(is_supervised_user, + version, std::move(url_loader_factory), kScriptsListUrlParam.Get()) {} PasswordScriptsFetcherImpl::PasswordScriptsFetcherImpl( + bool is_supervised_user, const base::Version& version, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::string scripts_list_url) - : version_(version), + : is_supervised_user_(is_supervised_user), + version_(version), scripts_list_url_(std::move(scripts_list_url)), url_loader_factory_(std::move(url_loader_factory)) {} @@ -282,6 +286,12 @@ } bool PasswordScriptsFetcherImpl::IsCacheStale() const { + // For supervised users, we always simulate a fresh cache to avoid fetching + // scripts. + if (is_supervised_user_) { + return false; + } + static const base::TimeDelta kCacheTimeout( base::Minutes(kCacheTimeoutInMinutes)); return last_fetch_timestamp_.is_null() ||
diff --git a/components/password_manager/core/browser/password_scripts_fetcher_impl.h b/components/password_manager/core/browser/password_scripts_fetcher_impl.h index 3447813..c0d7860 100644 --- a/components/password_manager/core/browser/password_scripts_fetcher_impl.h +++ b/components/password_manager/core/browser/password_scripts_fetcher_impl.h
@@ -19,14 +19,14 @@ #include "components/password_manager/core/browser/password_scripts_fetcher.h" #include "services/network/public/cpp/simple_url_loader.h" -namespace url { -class Origin; -} - namespace network { class SharedURLLoaderFactory; } +namespace url { +class Origin; +} + namespace password_manager { extern const char kDefaultChangePasswordScriptsListUrl[]; @@ -51,9 +51,11 @@ // The first constructor calls the second one. The second one is called // directly only from tests. PasswordScriptsFetcherImpl( + bool is_supervised_user, const base::Version& version, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); PasswordScriptsFetcherImpl( + bool is_supervised_user, const base::Version& version, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::string scripts_list_url); @@ -95,6 +97,11 @@ // Runs |callback| immediately with the script availability for |origin|. void RunResponseCallback(url::Origin origin, ResponseCallback callback); + // Indicates whether the user has a supervised account - for those, script + // availability already returns `false` unless overwritten by the + // `kForceEnablePasswordDomainCapabilities` feature. + const bool is_supervised_user_; + const base::Version version_; // URL to fetch a list of scripts from.
diff --git a/components/password_manager/core/browser/password_scripts_fetcher_impl_unittests.cc b/components/password_manager/core/browser/password_scripts_fetcher_impl_unittest.cc similarity index 90% rename from components/password_manager/core/browser/password_scripts_fetcher_impl_unittests.cc rename to components/password_manager/core/browser/password_scripts_fetcher_impl_unittest.cc index 6913963..20235a1 100644 --- a/components/password_manager/core/browser/password_scripts_fetcher_impl_unittests.cc +++ b/components/password_manager/core/browser/password_scripts_fetcher_impl_unittest.cc
@@ -16,6 +16,7 @@ #include "testing/gtest/include/gtest/gtest.h" using ::testing::Pair; +using ::testing::Return; using ::testing::UnorderedElementsAre; namespace { @@ -68,7 +69,8 @@ namespace password_manager { class PasswordScriptsFetcherImplTest : public ::testing::Test { public: - void Reinitialize(const base::Version& version) { + void Reinitialize(const base::Version& version, + bool is_supervised_user = false) { recorded_responses_.clear(); test_url_loader_factory_ = std::make_unique<network::TestURLLoaderFactory>(); @@ -76,7 +78,8 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( test_url_loader_factory_.get()); fetcher_ = std::make_unique<PasswordScriptsFetcherImpl>( - version, test_shared_loader_factory_); + /* is_supervised_user= */ is_supervised_user, version, + test_shared_loader_factory_); } void SetUp() override { @@ -362,6 +365,41 @@ EXPECT_EQ(0, GetNumberOfPendingRequests()); } +TEST_F(PasswordScriptsFetcherImplTest, IsScriptAvailableForSupervisedUser) { + // Simulate a supervised user. + Reinitialize(GetVersion(), /*is_supervised_user=*/true); + // `IsScriptAvailable` does not trigger any network requests and returns + // false. + EXPECT_FALSE(fetcher()->IsScriptAvailable(GetOriginWithScript1())); + EXPECT_FALSE(fetcher()->IsScriptAvailable(GetOriginWithoutScript())); + EXPECT_EQ(0, GetNumberOfPendingRequests()); + StartBulkCheck(); + // No request is ever started. + EXPECT_EQ(0, GetNumberOfPendingRequests()); + + // The results are still false. + EXPECT_FALSE(fetcher()->IsScriptAvailable(GetOriginWithScript1())); + EXPECT_FALSE(fetcher()->IsScriptAvailable(GetOriginWithoutScript())); +} + +TEST_F(PasswordScriptsFetcherImplTest, + IsScriptAvailableForSupervisedUserWithDomainFlagSet) { + // Simulate a supervised user. + Reinitialize(GetVersion(), /*is_supervised_user=*/true); + + EXPECT_FALSE(fetcher()->IsScriptAvailable(GetOriginWithScript1())); + EXPECT_FALSE(fetcher()->IsScriptAvailable(GetOriginWithoutScript())); + EXPECT_EQ(0, GetNumberOfPendingRequests()); + + base::test::ScopedFeatureList features; + features.InitAndEnableFeature( + password_manager::features::kForceEnablePasswordDomainCapabilities); + + // The flag overrides even supervised users. + EXPECT_TRUE(fetcher()->IsScriptAvailable(GetOriginWithScript1())); + EXPECT_TRUE(fetcher()->IsScriptAvailable(GetOriginWithoutScript())); +} + TEST_F(PasswordScriptsFetcherImplTest, EnablePasswordDomainCapabilitiesFlag) { // |kEnablePasswordDomainCapabilities| flag is disabled, |IsScriptAvailable| // returns the default value (false). @@ -403,7 +441,8 @@ scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory); - PasswordScriptsFetcherImpl fetcher(GetVersion(), test_shared_loader_factory, + PasswordScriptsFetcherImpl fetcher(/*is_supervised_user=*/false, GetVersion(), + test_shared_loader_factory, kNonDefaultScriptsListUrl); fetcher.PrewarmCache();
diff --git a/components/services/unzip/BUILD.gn b/components/services/unzip/BUILD.gn index 579d80d..47e54260 100644 --- a/components/services/unzip/BUILD.gn +++ b/components/services/unzip/BUILD.gn
@@ -46,6 +46,7 @@ visibility = [ ":unit_tests" ] testonly = true sources = [ + "//components/test/data/unzip_service/Duplicate Filenames.zip", "//components/test/data/unzip_service/SJIS 00.zip", "//components/test/data/unzip_service/SJIS 01.zip", "//components/test/data/unzip_service/SJIS 02.zip", @@ -61,6 +62,7 @@ "//components/test/data/unzip_service/SJIS 12.zip", "//components/test/data/unzip_service/SJIS 13.zip", "//components/test/data/unzip_service/UTF8 (Bug 903664).zip", + "//components/test/data/unzip_service/Wrong CRC.zip", "//components/test/data/unzip_service/bad_archive.zip", "//components/test/data/unzip_service/bug953599.zip", "//components/test/data/unzip_service/good_archive.zip",
diff --git a/components/services/unzip/public/cpp/unzip_unittest.cc b/components/services/unzip/public/cpp/unzip_unittest.cc index 9c663bf..2c79a817 100644 --- a/components/services/unzip/public/cpp/unzip_unittest.cc +++ b/components/services/unzip/public/cpp/unzip_unittest.cc
@@ -209,6 +209,20 @@ EXPECT_FALSE(some_files_empty); } +// Checks that the Unzipper service does not overwrite an existing file. +TEST_F(UnzipTest, DuplicatedNames) { + EXPECT_FALSE(DoUnzip(GetArchivePath("Duplicate Filenames.zip"), unzip_dir_)); + + // Check that the first file was correctly extracted. + std::string content; + EXPECT_TRUE( + base::ReadFileToString(unzip_dir_.AppendASCII("Simple.txt"), &content)); + EXPECT_EQ("Simple 1\n", content); + + // Check that no other file was extracted. + EXPECT_EQ(1, CountFiles(unzip_dir_)); +} + TEST_F(UnzipTest, DetectEncodingAbsentArchive) { EXPECT_EQ(UNKNOWN_ENCODING, DoDetectEncoding(GetArchivePath("absent_archive.zip")));
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index 3e68057b..3af0287 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -1822,6 +1822,7 @@ ASSERT_TRUE(reconcilor->is_reconcile_started_); } +#if BUILDFLAG(IS_CHROMEOS_ASH) // This test is needed until chrome changes to use gaia obfuscated id. // The primary account manager and token service use the gaia "email" property, // which preserves dots in usernames and preserves case. @@ -1831,10 +1832,9 @@ // "Dot.S@hmail.com", as seen by the token service, will be considered the same // as "dots@gmail.com" as returned by gaia::ParseListAccountsData(). TEST_F(AccountReconcilorMirrorTest, StartReconcileNoopWithDots) { - if (identity_test_env()->identity_manager()->GetAccountIdMigrationState() != - signin::IdentityManager::AccountIdMigrationState::MIGRATION_NOT_STARTED) { - return; - } + ASSERT_EQ( + identity_test_env()->identity_manager()->GetAccountIdMigrationState(), + signin::IdentityManager::AccountIdMigrationState::MIGRATION_DONE); AccountInfo account_info = ConnectProfileToAccount("Dot.S@gmail.com"); signin::SetListAccountsResponseOneAccount( @@ -1846,6 +1846,7 @@ base::RunLoop().RunUntilIdle(); ASSERT_FALSE(reconcilor->is_reconcile_started_); } +#endif TEST_F(AccountReconcilorMirrorTest, StartReconcileNoopMultiple) { AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc index 332053c..0ebf6bf0 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -39,11 +39,15 @@ enum class LoadTokenFromDBStatus { // Token was loaded. TOKEN_LOADED = 0, + + // DEPRECATED // Token was revoked as part of Dice migration. - TOKEN_REVOKED_DICE_MIGRATION = 1, + // TOKEN_REVOKED_DICE_MIGRATION = 1, + // Token was revoked because it is a secondary account and account consistency // is disabled. TOKEN_REVOKED_SECONDARY_ACCOUNT = 2, + // Token was revoked on load due to cookie settings. TOKEN_REVOKED_ON_LOAD = 3, @@ -86,17 +90,6 @@ LOAD_CREDENTIALS_FINISHED_WITH_UNKNOWN_ERRORS; } -// Returns whether the token service should be migrated to Dice. -// Migration can happen if the following conditions are met: -// - Token service Dice migration is not already done, -// - Account consistency is DiceMigration or greater. -// TODO(droger): Remove this code once Dice is fully enabled. -bool ShouldMigrateToDice(signin::AccountConsistencyMethod account_consistency, - PrefService* prefs) { - return account_consistency == signin::AccountConsistencyMethod::kDice && - !prefs->GetBoolean(prefs::kTokenServiceDiceCompatible); -} - } // namespace // This class sends a request to GAIA to revoke the given refresh token from @@ -240,12 +233,6 @@ network_connection_tracker_->RemoveNetworkConnectionObserver(this); } -// static -void MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs( - PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kTokenServiceDiceCompatible, false); -} - std::unique_ptr<OAuth2AccessTokenFetcher> MutableProfileOAuth2TokenServiceDelegate::CreateAccessTokenFetcher( const CoreAccountId& account_id, @@ -391,7 +378,6 @@ set_load_credentials_state( signin::LoadCredentialsState:: LOAD_CREDENTIALS_FINISHED_WITH_UNKNOWN_ERRORS); - MaybeDeletePreDiceTokens(); FinishLoadingCredentials(); return; } @@ -430,7 +416,6 @@ set_load_credentials_state( signin::LoadCredentialsState:: LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED); - MaybeDeletePreDiceTokens(); } // Make sure that we have an entry for |loading_primary_account_id_| in the @@ -465,10 +450,6 @@ void MutableProfileOAuth2TokenServiceDelegate::LoadAllCredentialsIntoMemory( const std::map<std::string, std::string>& db_tokens) { - std::string old_login_token; - bool migrate_to_dice = - ShouldMigrateToDice(account_consistency_, client_->GetPrefs()); - { ScopedBatchChange batch(this); @@ -478,10 +459,8 @@ std::string prefixed_account_id = iter->first; std::string refresh_token = iter->second; - if (IsLegacyRefreshTokenId(prefixed_account_id) && !refresh_token.empty()) - old_login_token = refresh_token; - - if (IsLegacyServiceId(prefixed_account_id)) { + if (IsLegacyRefreshTokenId(prefixed_account_id) || + IsLegacyServiceId(prefixed_account_id)) { if (token_web_data_) { VLOG(1) << "MutablePO2TS remove legacy refresh token for account id " << prefixed_account_id; @@ -503,26 +482,6 @@ ? LoadTokenFromDBStatus::TOKEN_LOADED : LoadTokenFromDBStatus::TOKEN_REVOKED_SECONDARY_ACCOUNT; - if (migrate_to_dice) { - // Revoke old hosted domain accounts as part of Dice migration. - AccountInfo account_info = - account_tracker_service_->GetAccountInfo(account_id); - bool is_hosted_domain = false; - if (account_info.hosted_domain.empty()) { - // The AccountInfo is incomplete. Use a conservative approximation. - is_hosted_domain = - !client_->IsNonEnterpriseUser(account_info.email); - } else { - is_hosted_domain = - (account_info.hosted_domain != kNoHostedDomainFound); - } - if (is_hosted_domain) { - load_account = false; - load_token_status = - LoadTokenFromDBStatus::TOKEN_REVOKED_DICE_MIGRATION; - } - } - if (load_account && revoke_all_tokens_on_load_) { if (account_id == loading_primary_account_id_) { RevokeCredentialsOnServer(refresh_token); @@ -548,16 +507,7 @@ } } } - - if (!old_login_token.empty()) { - DCHECK(!loading_primary_account_id_.empty()); - if (refresh_tokens_.count(loading_primary_account_id_) == 0) - UpdateCredentials(loading_primary_account_id_, old_login_token); - } } - - if (migrate_to_dice) - client_->GetPrefs()->SetBoolean(prefs::kTokenServiceDiceCompatible, true); } void MutableProfileOAuth2TokenServiceDelegate::UpdateCredentials( @@ -748,8 +698,6 @@ } void MutableProfileOAuth2TokenServiceDelegate::FinishLoadingCredentials() { - if (account_consistency_ == signin::AccountConsistencyMethod::kDice) - DCHECK(client_->GetPrefs()->GetBoolean(prefs::kTokenServiceDiceCompatible)); FireRefreshTokensLoaded(); } @@ -770,18 +718,3 @@ FireRefreshTokenRevoked(account_id); } } - -void MutableProfileOAuth2TokenServiceDelegate::MaybeDeletePreDiceTokens() { - DCHECK(load_credentials_state() == - signin::LoadCredentialsState:: - LOAD_CREDENTIALS_FINISHED_WITH_UNKNOWN_ERRORS || - load_credentials_state() == - signin::LoadCredentialsState:: - LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED); - - if (account_consistency_ == signin::AccountConsistencyMethod::kDice && - !client_->GetPrefs()->GetBoolean(prefs::kTokenServiceDiceCompatible)) { - RevokeAllCredentials(); - client_->GetPrefs()->SetBoolean(prefs::kTokenServiceDiceCompatible, true); - } -}
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h index 822e4e689..82a113ef 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
@@ -23,7 +23,6 @@ #include "net/base/backoff_entry.h" #include "services/network/public/cpp/network_connection_tracker.h" -class PrefRegistrySimple; class SigninClient; class TokenWebData; @@ -50,8 +49,6 @@ ~MutableProfileOAuth2TokenServiceDelegate() override; - static void RegisterProfilePrefs(PrefRegistrySimple* registry); - // Overridden from ProfileOAuth2TokenServiceDelegate. std::unique_ptr<OAuth2AccessTokenFetcher> CreateAccessTokenFetcher( const CoreAccountId& account_id, @@ -199,11 +196,6 @@ void RevokeCredentialsImpl(const CoreAccountId& account_id, bool revoke_on_server); - // If the Dice migration happened before the tokens could be migrated, delete - // all the tokens. This is only called if the tokens could not be loaded - // successfully. - void MaybeDeletePreDiceTokens(); - // Maps the |account_id| of accounts known to ProfileOAuth2TokenService // to information about the account. typedef std::map<CoreAccountId, AccountStatus> AccountStatusMap;
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc index edf02a38..4416c0a 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -49,30 +49,6 @@ static const char kLSOService[] = "lso"; static const char kEmail[] = "user@gmail.com"; -namespace { - -// Create test account info. -AccountInfo CreateTestAccountInfo(const std::string& name, - bool is_hosted_domain, - bool is_valid) { - AccountInfo account_info; - account_info.account_id = CoreAccountId(name); - account_info.gaia = name; - account_info.email = name + "@email.com"; - account_info.full_name = "name"; - account_info.given_name = "name"; - if (is_valid) { - account_info.hosted_domain = - is_hosted_domain ? "example.com" : kNoHostedDomainFound; - } - account_info.locale = "en"; - account_info.picture_url = "https://example.com"; - EXPECT_EQ(is_valid, account_info.IsValid()); - return account_info; -} - -} // namespace - class MutableProfileOAuth2TokenServiceDelegateTest : public testing::Test, public OAuth2AccessTokenConsumer, @@ -95,9 +71,6 @@ void SetUp() override { OSCryptMocker::SetUp(); - - MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs( - pref_service_.registry()); AccountTrackerService::RegisterPrefs(pref_service_.registry()); PrimaryAccountManager::RegisterProfilePrefs(pref_service_.registry()); client_ = std::make_unique<TestSigninClient>(&pref_service_); @@ -270,71 +243,31 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceDBUpgrade) { InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); - CoreAccountId main_account_id("account_id"); - std::string main_refresh_token("old_refresh_token"); + CoreAccountId primary_account_id("primaryAccount"); - // Populate DB with legacy tokens. + // Populate DB with legacy tokens (Expected to be discarded). AddAuthTokenManually(GaiaConstants::kSyncService, "syncServiceToken"); AddAuthTokenManually(kLSOService, "lsoToken"); AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken, - main_refresh_token); + "primaryLegacyRefreshToken"); // Force LoadCredentials. - oauth2_service_delegate_->LoadCredentials(main_account_id, + oauth2_service_delegate_->LoadCredentials(primary_account_id, /*is_syncing=*/false); base::RunLoop().RunUntilIdle(); - // Legacy tokens get discarded, but the old refresh token is kept. + // 1. Legacy tokens get all discarded. + // 2. Token for primary account is set to invalid as it cannot be found. + // 3. Token for secondary account is loaded. EXPECT_EQ(1, tokens_loaded_count_); EXPECT_EQ(1, token_available_count_); EXPECT_EQ(1, end_batch_changes_); - EXPECT_TRUE( - oauth2_service_delegate_->RefreshTokenIsAvailable(main_account_id)); EXPECT_EQ(1U, oauth2_service_delegate_->refresh_tokens_.size()); - EXPECT_EQ( - main_refresh_token, - oauth2_service_delegate_->refresh_tokens_[main_account_id].refresh_token); - - // Add an old legacy token to the DB, to ensure it will not overwrite existing - // credentials for main account. - AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken, - "secondOldRefreshToken"); - // Add some other legacy token. (Expected to get discarded). - AddAuthTokenManually(kLSOService, "lsoToken"); - // Also add a token using PO2TS.UpdateCredentials and make sure upgrade does - // not wipe it. - CoreAccountId other_account_id("other_account_id"); - std::string other_refresh_token("other_refresh_token"); - oauth2_service_delegate_->UpdateCredentials(other_account_id, - other_refresh_token); - ResetObserverCounts(); - - // Force LoadCredentials. - oauth2_service_delegate_->LoadCredentials(main_account_id, - /*is_syncing=*/false); - base::RunLoop().RunUntilIdle(); - - // Again legacy tokens get discarded, but since the main porfile account - // token is present it is not overwritten. - EXPECT_EQ(2, token_available_count_); - EXPECT_EQ(1, tokens_loaded_count_); - EXPECT_EQ(1, end_batch_changes_); - EXPECT_EQ(main_refresh_token, - oauth2_service_delegate_->GetRefreshToken(main_account_id)); EXPECT_TRUE( - oauth2_service_delegate_->RefreshTokenIsAvailable(main_account_id)); - // TODO(fgorski): cover both using RefreshTokenIsAvailable() and then get the - // tokens using GetRefreshToken() - EXPECT_EQ(2U, oauth2_service_delegate_->refresh_tokens_.size()); - EXPECT_EQ( - main_refresh_token, - oauth2_service_delegate_->refresh_tokens_[main_account_id].refresh_token); - EXPECT_EQ(other_refresh_token, - oauth2_service_delegate_->refresh_tokens_[other_account_id] + oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account_id)); + EXPECT_EQ(GaiaConstants::kInvalidRefreshToken, + oauth2_service_delegate_->refresh_tokens_[primary_account_id] .refresh_token); - - oauth2_service_delegate_->RevokeAllCredentials(); - EXPECT_EQ(2, end_batch_changes_); } TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, @@ -577,54 +510,6 @@ ResetObserverCounts(); } -// Checks that tokens are loaded and prefs::kTokenServiceDiceCompatible is set -// to true if the tokens are loaded after the Dice migration. -TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, LoadAfterDiceMigration) { - InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); - ASSERT_FALSE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); - - // Add account info to the account tracker. - AccountInfo primary_account = CreateTestAccountInfo( - "primary_account", false /* is_hosted_domain*/, true /* is_valid*/); - account_tracker_service_.SeedAccountInfo(primary_account); - AddAuthTokenManually("AccountId-" + primary_account.account_id.ToString(), - "refresh_token"); - - oauth2_service_delegate_->LoadCredentials(CoreAccountId(), - /*is_syncing=*/false); - base::RunLoop().RunUntilIdle(); - - EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable( - primary_account.account_id)); - EXPECT_EQ( - signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS, - oauth2_service_delegate_->load_credentials_state()); - - ASSERT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); -} - -// Checks that prefs::kTokenServiceDiceCompatible is set to true if the tokens -// are loaded after the Dice migration, even if there was a database read error. -TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, - LoadAfterDiceMigrationWithError) { - InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); - ASSERT_FALSE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); - - // Shutdown the database to trigger a database read error. - token_web_data_->ShutdownDatabase(); - - oauth2_service_delegate_->LoadCredentials(CoreAccountId(), - /*is_syncing=*/false); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(0u, oauth2_service_delegate_->GetAccounts().size()); - EXPECT_EQ(signin::LoadCredentialsState:: - LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED, - oauth2_service_delegate_->load_credentials_state()); - - ASSERT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); -} - TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, LoadCredentialsClearsTokenDBWhenNoPrimaryAccount_DiceDisabled) { // Populate DB with 2 valid tokens. @@ -838,7 +723,6 @@ } TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, LoadInvalidToken) { - pref_service_.SetBoolean(prefs::kTokenServiceDiceCompatible, true); InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); std::map<std::string, std::string> tokens; const CoreAccountId account_id("account_id");
diff --git a/components/signin/public/base/signin_client.cc b/components/signin/public/base/signin_client.cc index 1ddf8d9..93c2f4f 100644 --- a/components/signin/public/base/signin_client.cc +++ b/components/signin/public/base/signin_client.cc
@@ -10,7 +10,3 @@ // Allow sign out to continue. std::move(on_signout_decision_reached).Run(SignoutDecision::ALLOW_SIGNOUT); } - -bool SigninClient::IsNonEnterpriseUser(const std::string& username) { - return false; -}
diff --git a/components/signin/public/base/signin_client.h b/components/signin/public/base/signin_client.h index c40143fe..17e7e49 100644 --- a/components/signin/public/base/signin_client.h +++ b/components/signin/public/base/signin_client.h
@@ -91,11 +91,6 @@ GaiaAuthConsumer* consumer, gaia::GaiaSource source) = 0; - // Checks whether a user is known to be non-enterprise. Domains such as - // gmail.com and googlemail.com are known to not be managed. Also returns - // false if the username is empty. - virtual bool IsNonEnterpriseUser(const std::string& username); - #if BUILDFLAG(IS_CHROMEOS_LACROS) // Returns an account used to sign into Chrome OS session if available. virtual absl::optional<account_manager::Account>
diff --git a/components/signin/public/base/signin_pref_names.cc b/components/signin/public/base/signin_pref_names.cc index 579fd2b..1817c65 100644 --- a/components/signin/public/base/signin_pref_names.cc +++ b/components/signin/public/base/signin_pref_names.cc
@@ -85,9 +85,6 @@ // Boolean which stores if the user is allowed to signin to chrome. const char kSigninAllowed[] = "signin.allowed"; -// True if the token service has been prepared for Dice migration. -const char kTokenServiceDiceCompatible[] = "token_service.dice_compatible"; - // Contains last |ListAccounts| data which corresponds to Gaia cookies. const char kGaiaCookieLastListAccountsData[] = "gaia_cookie.last_list_accounts_data";
diff --git a/components/signin/public/base/signin_pref_names.h b/components/signin/public/base/signin_pref_names.h index c481c31..42b6295b 100644 --- a/components/signin/public/base/signin_pref_names.h +++ b/components/signin/public/base/signin_pref_names.h
@@ -30,7 +30,6 @@ extern const char kReverseAutologinRejectedEmailList[]; extern const char kSignedInWithCredentialProvider[]; extern const char kSigninAllowed[]; -extern const char kTokenServiceDiceCompatible[]; extern const char kGaiaCookieLastListAccountsData[]; } // namespace prefs
diff --git a/components/signin/public/base/test_signin_client.cc b/components/signin/public/base/test_signin_client.cc index 5cd2335..fd3cb4b 100644 --- a/components/signin/public/base/test_signin_client.cc +++ b/components/signin/public/base/test_signin_client.cc
@@ -112,10 +112,6 @@ GetURLLoaderFactory()); } -bool TestSigninClient::IsNonEnterpriseUser(const std::string& email) { - return gaia::ExtractDomainName(email) == "gmail.com"; -} - #if BUILDFLAG(IS_CHROMEOS_LACROS) absl::optional<account_manager::Account> TestSigninClient::GetInitialPrimaryAccount() {
diff --git a/components/signin/public/base/test_signin_client.h b/components/signin/public/base/test_signin_client.h index 5187034..d091d39a 100644 --- a/components/signin/public/base/test_signin_client.h +++ b/components/signin/public/base/test_signin_client.h
@@ -96,7 +96,6 @@ std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher( GaiaAuthConsumer* consumer, gaia::GaiaSource source) override; - bool IsNonEnterpriseUser(const std::string& email) override; #if BUILDFLAG(IS_CHROMEOS_LACROS) absl::optional<account_manager::Account> GetInitialPrimaryAccount() override;
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index f3875d1..223b74b 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -424,15 +424,13 @@ account_fetcher_service_->OnNetworkInitialized(); } +#if BUILDFLAG(IS_CHROMEOS_ASH) IdentityManager::AccountIdMigrationState IdentityManager::GetAccountIdMigrationState() const { -#if BUILDFLAG(IS_CHROMEOS_ASH) return static_cast<IdentityManager::AccountIdMigrationState>( account_tracker_service_->GetMigrationState()); -#else - return IdentityManager::AccountIdMigrationState::MIGRATION_DONE; -#endif } +#endif CoreAccountId IdentityManager::PickAccountIdForAccount( const std::string& gaia, @@ -452,9 +450,6 @@ AccountFetcherService::RegisterPrefs(registry); AccountTrackerService::RegisterPrefs(registry); GaiaCookieManagerService::RegisterPrefs(registry); -#if BUILDFLAG(ENABLE_DICE_SUPPORT) - MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs(registry); -#endif } DiagnosticsProvider* IdentityManager::GetDiagnosticsProvider() {
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h index 03aac66..912c2b7 100644 --- a/components/signin/public/identity_manager/identity_manager.h +++ b/components/signin/public/identity_manager/identity_manager.h
@@ -397,6 +397,7 @@ // initialized. void OnNetworkInitialized(); +#if BUILDFLAG(IS_CHROMEOS_ASH) // Methods related to migration of account IDs from email to Gaia ID. // TODO(https://crbug.com/883272): Remove these once all platforms have // migrated to the new account_id based on gaia (currently, only ChromeOS @@ -413,6 +414,7 @@ // Returns the currently saved state of the migration of account IDs. AccountIdMigrationState GetAccountIdMigrationState() const; +#endif // Picks the correct account_id for the specified account depending on the // migration state.
diff --git a/components/signin/public/identity_manager/identity_manager_unittest.cc b/components/signin/public/identity_manager/identity_manager_unittest.cc index d9f0f91..59cb4b3 100644 --- a/components/signin/public/identity_manager/identity_manager_unittest.cc +++ b/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -2405,10 +2405,12 @@ } #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(IdentityManagerTest, AccountIdMigration_DoneOnInitialization) { EXPECT_EQ(IdentityManager::AccountIdMigrationState::MIGRATION_DONE, identity_manager()->GetAccountIdMigrationState()); } +#endif // Checks that IdentityManager::Observer gets OnAccountUpdated when account info // is updated. @@ -2455,6 +2457,7 @@ TEST_F(IdentityManagerTest, TestPickAccountIdForAccount) { const CoreAccountId account_id = identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail); +#if BUILDFLAG(IS_CHROMEOS_ASH) const bool account_id_migration_done = identity_manager()->GetAccountIdMigrationState() == IdentityManager::AccountIdMigrationState::MIGRATION_DONE; @@ -2463,6 +2466,9 @@ } else { EXPECT_TRUE(gaia::AreEmailsSame(kTestEmail, account_id.ToString())); } +#else + EXPECT_TRUE(gaia::AreEmailsSame(kTestGaiaId, account_id.ToString())); +#endif } #if BUILDFLAG(IS_ANDROID)
diff --git a/components/test/data/unzip_service/Duplicate Filenames.zip b/components/test/data/unzip_service/Duplicate Filenames.zip new file mode 100644 index 0000000..584822d0 --- /dev/null +++ b/components/test/data/unzip_service/Duplicate Filenames.zip Binary files differ
diff --git a/components/ukm/test_ukm_recorder.cc b/components/ukm/test_ukm_recorder.cc index 3442278..83c67c7 100644 --- a/components/ukm/test_ukm_recorder.cc +++ b/components/ukm/test_ukm_recorder.cc
@@ -54,7 +54,7 @@ on_add_entry_ && entry && entry_hash_to_wait_for_ == entry->event_hash; UkmRecorderImpl::AddEntry(std::move(entry)); if (should_run_callback) - std::move(on_add_entry_).Run(); + on_add_entry_.Run(); } const UkmSource* TestUkmRecorder::GetSourceForSourceId( @@ -79,8 +79,9 @@ return nullptr; } -void TestUkmRecorder::SetOnAddEntryCallback(base::StringPiece entry_name, - base::OnceClosure on_add_entry) { +void TestUkmRecorder::SetOnAddEntryCallback( + base::StringPiece entry_name, + base::RepeatingClosure on_add_entry) { on_add_entry_ = std::move(on_add_entry); entry_hash_to_wait_for_ = base::HashMetricName(entry_name); }
diff --git a/components/ukm/test_ukm_recorder.h b/components/ukm/test_ukm_recorder.h index 39930e5..8f06175 100644 --- a/components/ukm/test_ukm_recorder.h +++ b/components/ukm/test_ukm_recorder.h
@@ -73,7 +73,7 @@ // Sets a callback that will be called when recording an entry for entry name. void SetOnAddEntryCallback(base::StringPiece entry_name, - base::OnceClosure on_add_entry); + base::RepeatingClosure on_add_entry); // Gets all of the entries recorded for entry name. std::vector<const mojom::UkmEntry*> GetEntriesByName( @@ -123,7 +123,7 @@ private: uint64_t entry_hash_to_wait_for_ = 0; - base::OnceClosure on_add_entry_; + base::RepeatingClosure on_add_entry_; }; // Similar to a TestUkmRecorder, but also sets itself as the global UkmRecorder
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc index 40e4b589..2daf396 100644 --- a/content/browser/back_forward_cache_features_browsertest.cc +++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -4290,62 +4290,9 @@ FROM_HERE); } -IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, - DoNotCacheIfMediaSessionPlaybackStateChanged) { - ASSERT_TRUE(embedded_test_server()->Start()); - - // 1) Navigate to a page using MediaSession. - EXPECT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); - RenderFrameHost* rfh_a = shell()->web_contents()->GetMainFrame(); - RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); - EXPECT_TRUE(ExecJs(rfh_a, R"( - navigator.mediaSession.metadata = new MediaMetadata({ - artwork: [ - {src: "test_image.jpg", sizes: "1x1", type: "image/jpeg"}, - {src: "test_image.jpg", sizes: "10x10", type: "image/jpeg"} - ] - }); - )")); - - // 2) Navigate away. - EXPECT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL("b.com", "/title1.html"))); - - // 3) Go back. - ASSERT_TRUE(HistoryGoBack(web_contents())); - - // The page is restored since the playback state is not changed. - ExpectRestored(FROM_HERE); - - // 4) Modify the playback state of the media session. - EXPECT_TRUE(ExecJs(rfh_a, R"( - navigator.mediaSession.playbackState = 'playing'; - )")); - - // 5) Navigate away. - EXPECT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL("b.com", "/title1.html"))); - - // 6) Go back. - ASSERT_TRUE(HistoryGoBack(web_contents())); - - // The page is not restored due to the playback. - auto reason = BackForwardCacheDisable::DisabledReason( - BackForwardCacheDisable::DisabledReasonId::kMediaSession); - ExpectNotRestored({NotRestoredReason::kDisableForRenderFrameHostCalled}, {}, - {}, {reason}, {}, FROM_HERE); -} - -class BackForwardCacheBrowserTestWithMediaSessionPlaybackStateChangeSupported +class BackForwardCacheBrowserTestWithMediaSession : public BackForwardCacheBrowserTest { protected: - void SetUpCommandLine(base::CommandLine* command_line) override { - EnableFeatureAndSetParams(kBackForwardCacheMediaSessionPlaybackStateChange, - "", ""); - BackForwardCacheBrowserTest::SetUpCommandLine(command_line); - } - void PlayVideoNavigateAndGoBack() { MediaSession* media_session = MediaSession::Get(shell()->web_contents()); ASSERT_TRUE(media_session); @@ -4370,9 +4317,8 @@ } }; -IN_PROC_BROWSER_TEST_F( - BackForwardCacheBrowserTestWithMediaSessionPlaybackStateChangeSupported, - CacheWhenMediaSessionPlaybackStateIsChanged) { +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithMediaSession, + CacheWhenMediaSessionPlaybackStateIsChanged) { ASSERT_TRUE(embedded_test_server()->Start()); // 1) Navigate to a page. @@ -4395,9 +4341,8 @@ ExpectRestored(FROM_HERE); } -IN_PROC_BROWSER_TEST_F( - BackForwardCacheBrowserTestWithMediaSessionPlaybackStateChangeSupported, - CacheWhenMediaSessionServiceIsNotUsed) { +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithMediaSession, + CacheWhenMediaSessionServiceIsNotUsed) { // There are sometimes unexpected messages from a renderer to the browser, // which caused test flakiness. // TODO(crbug.com/1253200): Fix the test flakiness. @@ -4418,9 +4363,8 @@ ExpectRestored(FROM_HERE); } -IN_PROC_BROWSER_TEST_F( - BackForwardCacheBrowserTestWithMediaSessionPlaybackStateChangeSupported, - DontCacheWhenMediaSessionServiceIsUsed) { +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithMediaSession, + DontCacheWhenMediaSessionServiceIsUsed) { ASSERT_TRUE(embedded_test_server()->Start()); // Navigate to a page using MediaSession.
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index aa7b51d..fd4a966 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1696,9 +1696,6 @@ ContentWebBluetooth; case BackForwardCacheDisable::DisabledReasonId::kWebUSB: return Page::BackForwardCacheNotRestoredReasonEnum::ContentWebUSB; - case BackForwardCacheDisable::DisabledReasonId::kMediaSession: - return Page::BackForwardCacheNotRestoredReasonEnum:: - ContentMediaSession; case BackForwardCacheDisable::DisabledReasonId::kMediaSessionService: return Page::BackForwardCacheNotRestoredReasonEnum:: ContentMediaSessionService;
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index 96b804e1..c17c097 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -1429,16 +1429,6 @@ void MediaSessionImpl::OnMediaSessionPlaybackStateChanged( MediaSessionServiceImpl* service) { - if (!BackForwardCacheImpl::IsMediaSessionPlaybackStateChangedAllowed()) { - // Even though the back-forward cache is allowed at OnServiceCreated, it is - // disabled when the playback state is changed as this affects the visible - // UI for MediaSession. - BackForwardCache::DisableForRenderFrameHost( - service->GetRenderFrameHostId(), - BackForwardCacheDisable::DisabledReason( - BackForwardCacheDisable::DisabledReasonId::kMediaSession)); - } - if (service != routed_service_) return;
diff --git a/content/browser/renderer_host/back_forward_cache_disable.cc b/content/browser/renderer_host/back_forward_cache_disable.cc index e7d34947..e775da4 100644 --- a/content/browser/renderer_host/back_forward_cache_disable.cc +++ b/content/browser/renderer_host/back_forward_cache_disable.cc
@@ -28,8 +28,6 @@ return "WebBluetooth"; case BackForwardCacheDisable::DisabledReasonId::kWebUSB: return "WebUSB"; - case BackForwardCacheDisable::DisabledReasonId::kMediaSession: - return "MediaSession"; case BackForwardCacheDisable::DisabledReasonId::kMediaSessionService: return "MediaSessionService"; case BackForwardCacheDisable::DisabledReasonId::kScreenReader:
diff --git a/content/browser/renderer_host/back_forward_cache_disable.h b/content/browser/renderer_host/back_forward_cache_disable.h index 955c787..b0d3312 100644 --- a/content/browser/renderer_host/back_forward_cache_disable.h +++ b/content/browser/renderer_host/back_forward_cache_disable.h
@@ -32,7 +32,7 @@ kWebUSB = 9, // MediaSession's playback state is changed (crbug.com/1177661). - kMediaSession = 10, + // kMediaSession = 10 Removed after implementing support // MediaSession's service is used (crbug.com/1243599). kMediaSessionService = 11,
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc index 7ea4659d..455716ed 100644 --- a/content/browser/renderer_host/back_forward_cache_impl.cc +++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -1344,11 +1344,6 @@ return false; } -bool BackForwardCacheImpl::IsMediaSessionPlaybackStateChangedAllowed() { - return base::FeatureList::IsEnabled( - kBackForwardCacheMediaSessionPlaybackStateChange); -} - bool BackForwardCacheImpl::IsMediaSessionServiceAllowed() { return base::FeatureList::IsEnabled( features::kBackForwardCacheMediaSessionService);
diff --git a/content/browser/renderer_host/back_forward_cache_impl.h b/content/browser/renderer_host/back_forward_cache_impl.h index 7014357..5a94660 100644 --- a/content/browser/renderer_host/back_forward_cache_impl.h +++ b/content/browser/renderer_host/back_forward_cache_impl.h
@@ -61,12 +61,6 @@ "CacheControlNoStoreEnterBackForwardCache", base::FEATURE_DISABLED_BY_DEFAULT}; -// Allows pages with MediaSession's playback state change to stay eligible for -// the back/forward cache. -const base::Feature kBackForwardCacheMediaSessionPlaybackStateChange{ - "BackForwardCacheMediaSessionPlaybackStateChange", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables controlling the time to live for pages in the backforward cache. // The time to live is defined by the param 'time_to_live_seconds'; if this // param is not specified then this feature is ignored and the default is used. @@ -186,10 +180,6 @@ ~BackForwardCacheImpl() override; - // Returns whether MediaSession's playback state change is allowed for the - // BackForwardCache. - static bool IsMediaSessionPlaybackStateChangedAllowed(); - // Returns whether MediaSession's service is allowed for the BackForwardCache. static bool IsMediaSessionServiceAllowed();
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index d0300c6..32297a4 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -231,6 +231,8 @@ #include "third_party/blink/public/common/permissions/permission_utils.h" #include "third_party/blink/public/common/permissions_policy/document_policy.h" #include "third_party/blink/public/common/permissions_policy/permissions_policy.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/broadcastchannel/broadcast_channel.mojom.h" @@ -1119,6 +1121,25 @@ std::move(callback)); } +// Records the identifiable surface metric associated with a document created +// event when the identifiability study is active. +void RecordIdentifiabilityDocumentCreatedMetrics( + const ukm::SourceId document_ukm_source_id, + ukm::UkmRecorder* ukm_recorder, + ukm::SourceId navigation_source_id, + bool is_cross_origin_frame, + bool is_cross_site_frame, + bool is_main_frame) { + if (blink::IdentifiabilityStudySettings::Get()->IsActive()) { + blink::IdentifiabilityStudyDocumentCreated(document_ukm_source_id) + .SetNavigationSourceId(navigation_source_id) + .SetIsMainFrame(is_main_frame) + .SetIsCrossOriginFrame(is_cross_origin_frame) + .SetIsCrossSiteFrame(is_cross_site_frame) + .Record(ukm_recorder); + } +} + } // namespace class RenderFrameHostImpl::SubresourceLoaderFactoriesConfig { @@ -13318,6 +13339,10 @@ .SetIsCrossOriginFrame(is_cross_origin_frame) .SetIsCrossSiteFrame(is_cross_site_frame) .Record(ukm_recorder); + + RecordIdentifiabilityDocumentCreatedMetrics( + document_ukm_source_id, ukm_recorder, GetPageUkmSourceId(), + is_cross_origin_frame, is_cross_site_frame, IsOutermostMainFrame()); } void RenderFrameHostImpl::BindReportingObserver(
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 246588c..a833f0102 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -371,6 +371,7 @@ blink::features::kPrefersColorSchemeClientHintHeader}, {"FirstPartySets", features::kFirstPartySets}, {"SanitizerAPI", blink::features::kSanitizerAPI}, + {"SanitizerAPIv0", blink::features::kSanitizerAPIv0}, {"SecureContextFixForWorkers", blink::features::kSecureContextFixForWorkers}, {"StorageAccessAPI", blink::features::kStorageAccessAPI},
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index 4c43325..71f75c61 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -323,6 +323,15 @@ * [`//chrome/browser/ui/webui/chromeos/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chrome/browser/ui/webui/chromeos/chromebox_for_meetings/) * [`//chrome/test/data/webui/chromeos/chromebox_for_meetings/.+`](https://cs.chromium.org/chromium/src/chrome/test/data/webui/chromeos/chromebox_for_meetings/) +* [linux-perfetto-rel](https://ci.chromium.org/p/chromium/builders/try/linux-perfetto-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-perfetto-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-perfetto-rel"")) + + Path regular expressions: + * [`//base/trace_event/.+`](https://cs.chromium.org/chromium/src/base/trace_event/) + * [`//base/tracing/.+`](https://cs.chromium.org/chromium/src/base/tracing/) + * [`//components/tracing/.+`](https://cs.chromium.org/chromium/src/components/tracing/) + * [`//content/browser/tracing/.+`](https://cs.chromium.org/chromium/src/content/browser/tracing/) + * [`//services/tracing/.+`](https://cs.chromium.org/chromium/src/services/tracing/) + * [linux_chromium_dbg_ng](https://ci.chromium.org/p/chromium/builders/try/linux_chromium_dbg_ng) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux_chromium_dbg_ng"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux_chromium_dbg_ng"")) Path regular expressions: @@ -486,16 +495,6 @@ * [linux-lacros-rel-code-coverage](https://ci.chromium.org/p/chromium/builders/try/linux-lacros-rel-code-coverage) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-lacros-rel-code-coverage"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-lacros-rel-code-coverage"")) * Experiment percentage: 3.0 -* [linux-perfetto-rel](https://ci.chromium.org/p/chromium/builders/try/linux-perfetto-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-perfetto-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-perfetto-rel"")) - * Experiment percentage: 100.0 - - Path regular expressions: - * [`//base/trace_event/.+`](https://cs.chromium.org/chromium/src/base/trace_event/) - * [`//base/tracing/.+`](https://cs.chromium.org/chromium/src/base/tracing/) - * [`//components/tracing/.+`](https://cs.chromium.org/chromium/src/components/tracing/) - * [`//content/browser/tracing/.+`](https://cs.chromium.org/chromium/src/content/browser/tracing/) - * [`//services/tracing/.+`](https://cs.chromium.org/chromium/src/services/tracing/) - * [linux-rel-ml](https://ci.chromium.org/p/chromium/builders/try/linux-rel-ml) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-rel-ml"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-rel-ml"")) * Experiment percentage: 5.0
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg index ee5db54..5b666e0 100644 --- a/infra/config/generated/cq-usage/full.cfg +++ b/infra/config/generated/cq-usage/full.cfg
@@ -393,6 +393,16 @@ location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { + name: "chromium/try/linux-perfetto-rel" + location_regexp: ".+/[+]/base/trace_event/.+" + location_regexp: ".+/[+]/base/tracing/.+" + location_regexp: ".+/[+]/components/tracing/.+" + location_regexp: ".+/[+]/content/browser/tracing/.+" + location_regexp: ".+/[+]/services/tracing/.+" + location_regexp_exclude: ".+/[+]/docs/.+" + location_regexp_exclude: ".+/[+]/infra/config/.+" + } + builders { name: "chromium/try/linux-rel" location_regexp: ".*" location_regexp_exclude: ".+/[+]/docs/.+"
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 7d5707c..aed0d701 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1389,7 +1389,6 @@ } builders { name: "chromium/try/linux-perfetto-rel" - experiment_percentage: 100 location_regexp: ".+/[+]/base/trace_event/.+" location_regexp: ".+/[+]/base/tracing/.+" location_regexp: ".+/[+]/components/tracing/.+"
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star index 25ba279..470a1d3d 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -223,7 +223,6 @@ try_.builder( name = "linux-perfetto-rel", tryjob = try_.job( - experiment_percentage = 100, location_regexp = [ ".+/[+]/base/trace_event/.+", ".+/[+]/base/tracing/.+",
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm index 23a3b9f3..7f1d4b2 100644 --- a/ios/chrome/browser/signin/authentication_service.mm +++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -119,9 +119,6 @@ signin::Tribool device_restore_session = IsFirstSessionAfterDeviceRestore(); initialized_ = true; - DCHECK_EQ(identity_manager_->GetAccountIdMigrationState(), - signin::IdentityManager::AccountIdMigrationState::MIGRATION_DONE); - identity_manager_observation_.Observe(identity_manager_); HandleForgottenIdentity(nil, /*should_prompt=*/true, device_restore_session == signin::Tribool::kTrue);
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm index 71c7ff8..9436b994 100644 --- a/ios/chrome/browser/signin/authentication_service_unittest.mm +++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -96,9 +96,6 @@ AuthenticationServiceFactory::CreateAndInitializeForBrowserState( browser_state_.get(), std::make_unique<AuthenticationServiceDelegateFake>()); - // Account ID migration is done on iOS. - DCHECK_EQ(signin::IdentityManager::MIGRATION_DONE, - identity_manager()->GetAccountIdMigrationState()); } std::unique_ptr<sync_preferences::PrefServiceSyncable> CreatePrefService() {
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 926fe014..023b6628 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -f50ad10b4d9207c5eb42bdcd46680c7a0ae8c89c \ No newline at end of file +4eeded0b4ce0ac50ec1264b0d9afe03228c09182 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 47e80ad2..414686d 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -10419ff61376fcaf3a3e7e69c5d0c90cff7dca66 \ No newline at end of file +a42b79e7da78f126d44f9eb364b37ce4ce35a986 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index e8dc57c..4a18784 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -8585721cea4e80ae98924723dea48a202ccb2586 \ No newline at end of file +2e251449db311f24a1cea7d24dbb60acbf90383d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index d3081b1..83f910ca 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -dbadb508fc68454469e22f355a01de6240e15714 \ No newline at end of file +fb899520360fe504d1443dd4190da4c9342adaa2 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index 2b168d5..8af8e3c 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -9347181c2b2317dddbad23b1091f7d968e2b98d1 \ No newline at end of file +cb43561f62e08f16a6a6024ae4de2ff4fc2a5c9f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index fbc80eae..1b38f38 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -d34e4841bf4289b1f1284bab52c7fc2451f8835d \ No newline at end of file +06ff62a0123a766a1dc3096ca8bf2272be84f7ed \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index d02ba8c8..d940d70 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -ae056876cced57265ecf6f955faa9c7b896ab21f \ No newline at end of file +7066e294ea277904bbc8a2b88faecfd400a36270 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 9c54e4a..88b2668 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -4027327213cff89a221cae6cd518256f6ef27b38 \ No newline at end of file +d24995eaeb8613e7692001d43a9ec01df06cb60c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 02146a2..d66dad0 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -117c529c5c72be62501873c9f5ca6c25f1137840 \ No newline at end of file +afd7adc0125c5f65fc11fdcc9d69e55f935e7008 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 7f1dbec..f46905d 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c0d7937230eec117c0b98d5079b27fd2d80493b5 \ No newline at end of file +768359bd58afc3bda7d25db6b7711c8aacb5bf1a \ No newline at end of file
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index fbb9038..2fa51612 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -24,6 +24,9 @@ } config("config") { + common_flags = [ "-fapplication-extension" ] + cflags_objc = common_flags + cflags_objcc = common_flags defines = [ "CWV_IMPLEMENTATION" ] frameworks = [ "CoreGraphics.framework", @@ -402,6 +405,8 @@ output_name = ios_web_view_output_name info_plist_target = ":info_plist" + ldflags = [ "-fapplication-extension" ] + public_headers = get_target_outputs(":web_view_umbrella_header") public_headers += ios_web_view_public_headers if (ios_web_view_include_cronet) {
diff --git a/media/capture/video/win/video_capture_device_factory_win.cc b/media/capture/video/win/video_capture_device_factory_win.cc index 8fb4433..ac02f906 100644 --- a/media/capture/video/win/video_capture_device_factory_win.cc +++ b/media/capture/video/win/video_capture_device_factory_win.cc
@@ -125,7 +125,9 @@ // Acer Aspire f5-573g. See https://crbug.com/1034644. "0bda:57f2", // Elgato Camlink 4k - "0fd9:0066"}; + "0fd9:0066", + // ACER Aspire VN7-571G. See https://crbug.com/1327948. + "04f2:b469"}; // Use this list only for non-USB webcams. const char* const kDisplayNamesBlockedForMediaFoundation[] = {
diff --git a/media/mojo/mojom/speech_recognition_service.mojom b/media/mojo/mojom/speech_recognition_service.mojom index c7046d30..cd161cb 100644 --- a/media/mojo/mojom/speech_recognition_service.mojom +++ b/media/mojo/mojom/speech_recognition_service.mojom
@@ -20,11 +20,11 @@ kHighlyConfident, }; -// The main interface a client uses to interact with a speech recognition -// service process. In Live Caption, every renderer can own one or more -// Remote<SpeechRecognitionContext>, with the receiver bound through the -// BrowserInterfaceBroker. In Chrome OS features like Dictation and Projector, -// every OnDeviceSpeechRecognizer can own a Remote<SpeechRecognitionContext>. +// The main interface a renderer client uses to interact with a speech +// recognition service process. In Live Caption, every renderer can own one or +// more Remote<SpeechRecognitionContext>, with the receiver bound through the +// BrowserInterfaceBroker. This is a stable interface that is used across the +// LaCrOS/Ash boundary. interface SpeechRecognitionContext { // Bind the recognizers to the speech recognition service. Returns a flag // indicating whether multichannel audio is supported by the speech @@ -33,15 +33,22 @@ pending_remote<SpeechRecognitionRecognizerClient> client, SpeechRecognitionOptions options) => (bool is_multichannel_supported); +}; +// Like a SpeechRecognitionContext, except it binds AudioSourceFetcher speech +// recognizer objects, rather than SpeechRecognitionRecognizer objects. In +// Chrome OS features like Dictation and Projector, every +// OnDeviceSpeechRecognizer can own a +// Remote<AudioSourceSpeechRecognitionContext>. +interface AudioSourceSpeechRecognitionContext { // Prepares microphone audio to be captured from within the // SpeechRecognitionService process, with results passed back to the // SpeechRecognitionRecognizerClient. BindAudioSourceFetcher( - pending_receiver<AudioSourceFetcher> fetcher_receiver, - pending_remote<SpeechRecognitionRecognizerClient> client, - SpeechRecognitionOptions options) - => (bool is_multichannel_supported); + pending_receiver<AudioSourceFetcher> fetcher_receiver, + pending_remote<SpeechRecognitionRecognizerClient> client, + SpeechRecognitionOptions options) + => (bool is_multichannel_supported); }; // The main interface to a speech secognition service process. @@ -49,13 +56,19 @@ // acquired during process launch. [ServiceSandbox=sandbox.mojom.Sandbox.kSpeechRecognition] interface SpeechRecognitionService { - // Bind the context to a new instance of the speech recognition. - BindContext(pending_receiver<SpeechRecognitionContext> context); + // Binds a new SpeechRecognitionContext hosted in the service process. + BindSpeechRecognitionContext( + pending_receiver<SpeechRecognitionContext> context); + + // Binds a new AudioSourceSpeechRecognitionContext hosted in the service + // process. + BindAudioSourceSpeechRecognitionContext( + pending_receiver<AudioSourceSpeechRecognitionContext> context); // Sets the file path to the Speech On-Device API (SODA) binary and // the config file for the language pack. SetSodaPath(mojo_base.mojom.FilePath binary_path, - mojo_base.mojom.FilePath config_path); + mojo_base.mojom.FilePath config_path); }; // The interface used to start and stop fetching audio from the microphone
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 2dd2dc6e..839f71f 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -1153,6 +1153,9 @@ cache_pending_ = true; net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY); first_cache_access_since_ = TimeTicks::Now(); + const bool has_opened_or_created_entry = has_opened_or_created_entry_; + has_opened_or_created_entry_ = true; + record_entry_open_or_creation_time_ = false; // See if we already have something working with this cache key. new_entry_ = cache_->FindActiveEntry(cache_key_); @@ -1181,6 +1184,10 @@ UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); } + if (!has_opened_or_created_entry) { + record_entry_open_or_creation_time_ = true; + } + // mode_ can be anything but NONE or WRITE at this point (READ, UPDATE, or // READ_WRITE). // READ, UPDATE, certain READ_WRITEs, and some methods shouldn't create, so @@ -1202,6 +1209,13 @@ "HttpCacheTransaction::DoOpenOrCreateEntryComplete", net_log().source().id, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + + const bool record_uma = + record_entry_open_or_creation_time_ && cache_ && + cache_->GetCurrentBackend() && + cache_->GetCurrentBackend()->GetCacheType() != MEMORY_CACHE; + record_entry_open_or_creation_time_ = false; + // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is // OK, otherwise the cache will end up with an active entry without any // transaction attached. @@ -1211,7 +1225,19 @@ cache_pending_ = false; if (result == OK) { - if (new_entry_->opened == false) { + if (new_entry_->opened) { + if (record_uma) { + base::UmaHistogramTimes( + "HttpCache.OpenDiskEntry", + base::TimeTicks::Now() - first_cache_access_since_); + } + } else { + if (record_uma) { + base::UmaHistogramTimes( + "HttpCache.CreateDiskEntry", + base::TimeTicks::Now() - first_cache_access_since_); + } + // Entry was created so mode changes to WRITE. mode_ = WRITE; }
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index 0b72fc4..bf7db0e 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h
@@ -700,6 +700,8 @@ base::TimeTicks read_headers_since_; base::Time open_entry_last_used_; bool recorded_histograms_; + bool has_opened_or_created_entry_ = false; + bool record_entry_open_or_creation_time_ = false; NetworkTransactionInfo network_transaction_info_;
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc index ec111648..93ffc6f6 100644 --- a/net/spdy/buffered_spdy_framer.cc +++ b/net/spdy/buffered_spdy_framer.cc
@@ -56,6 +56,7 @@ } void BufferedSpdyFramer::OnHeaders(spdy::SpdyStreamId stream_id, + size_t payload_length, bool has_priority, int weight, spdy::SpdyStreamId parent_stream_id, @@ -217,6 +218,7 @@ } void BufferedSpdyFramer::OnContinuation(spdy::SpdyStreamId stream_id, + size_t payload_length, bool end) {} bool BufferedSpdyFramer::OnUnknownFrame(spdy::SpdyStreamId stream_id,
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h index 1d91c4a..7679ca6 100644 --- a/net/spdy/buffered_spdy_framer.h +++ b/net/spdy/buffered_spdy_framer.h
@@ -156,6 +156,7 @@ void OnError(http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error, std::string detailed_error) override; void OnHeaders(spdy::SpdyStreamId stream_id, + size_t payload_length, bool has_priority, int weight, spdy::SpdyStreamId parent_stream_id, @@ -193,7 +194,9 @@ void OnDataFrameHeader(spdy::SpdyStreamId stream_id, size_t length, bool fin) override; - void OnContinuation(spdy::SpdyStreamId stream_id, bool end) override; + void OnContinuation(spdy::SpdyStreamId stream_id, + size_t payload_length, + bool end) override; void OnPriority(spdy::SpdyStreamId stream_id, spdy::SpdyStreamId parent_stream_id, int weight,
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h index 028f979..4e7425c 100644 --- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h +++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h
@@ -144,6 +144,11 @@ void QuichePrintCommandLineFlagHelpImpl(const char* usage); +template <typename T> +T GetQuicheCommandLineFlag(const T& flag) { + return flag; +} + } // namespace quiche #endif // NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_COMMAND_LINE_FLAGS_IMPL_H_
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 1f343f2..71582597 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -8240,15 +8240,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8325,15 +8325,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--client-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8750,15 +8750,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8835,15 +8835,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--impl-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index ef9a3f5..6c13935 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -46214,15 +46214,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46299,15 +46299,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--client-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46724,15 +46724,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46809,15 +46809,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--impl-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47238,15 +47238,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47323,15 +47323,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--client-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47748,15 +47748,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47833,15 +47833,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--impl-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48330,15 +48330,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48415,15 +48415,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--client-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48840,15 +48840,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48925,15 +48925,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--impl-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49422,15 +49422,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--client-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49507,15 +49507,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", - "--client-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--client-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--client-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49932,15 +49932,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M102/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M102/out/Release", "--impl-version=102", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -50017,15 +50017,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", - "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--implementation-outdir", - "../../weblayer_instrumentation_test_M103/out/Release", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", + "--webview-apk-path=apks/SystemWebView.apk", + "--implementation-outdir", + "../../weblayer_instrumentation_test_M103/out/Release", "--impl-version=103", "--gs-results-bucket=chromium-result-details", "--recover-devices",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 141ba98..c6f7a6e3 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5865,21 +5865,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5091.0", + "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -5892,7 +5892,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "isolate_profile_data": true, @@ -6030,21 +6030,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -6056,7 +6056,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "args": [ @@ -6176,21 +6176,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -6202,7 +6202,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 78980a4a..34d2ce66c 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -88037,21 +88037,21 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5091.0", + "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -88059,7 +88059,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "isolate_profile_data": true, @@ -88172,28 +88172,28 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "args": [ @@ -88293,28 +88293,28 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "isolate_profile_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "isolate_profile_data": true, @@ -89652,20 +89652,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5091.0", + "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -89679,7 +89679,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "merge": { @@ -89817,20 +89817,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -89843,7 +89843,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "args": [ @@ -89963,20 +89963,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -89989,7 +89989,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "merge": { @@ -91485,20 +91485,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5091.0", + "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -91512,7 +91512,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "merge": { @@ -91650,20 +91650,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -91676,7 +91676,7 @@ }, "test": "lacros_chrome_browsertests", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "args": [ @@ -91796,20 +91796,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5091.0", + "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -91822,7 +91822,7 @@ }, "test": "lacros_chrome_browsertests_run_in_series", "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" }, { "merge": { @@ -92557,20 +92557,20 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5091.0", + "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5092.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v104.0.5091.0", - "revision": "version:104.0.5091.0" + "location": "lacros_version_skew_tests_v104.0.5092.0", + "revision": "version:104.0.5092.0" } ], "dimension_sets": [ @@ -92583,7 +92583,7 @@ }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/", - "variant_id": "Lacros version skew testing ash 104.0.5091.0" + "variant_id": "Lacros version skew testing ash 104.0.5092.0" } ] },
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index f69594a..44062a2a 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5091.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5092.0/test_ash_chrome', ], - 'identifier': 'Lacros version skew testing ash 104.0.5091.0', + 'identifier': 'Lacros version skew testing ash 104.0.5092.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v104.0.5091.0', - 'revision': 'version:104.0.5091.0', + 'location': 'lacros_version_skew_tests_v104.0.5092.0', + 'revision': 'version:104.0.5092.0', }, ], }, @@ -462,16 +462,16 @@ }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MILESTONE': { 'args': [ - '--webview-apk-path=apks/AOSP_SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--implementation-outdir', - '../../weblayer_instrumentation_test_M103/out/Release', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--impl-version=103', + '--webview-apk-path=apks/AOSP_SystemWebView.apk', + '--implementation-outdir', + '../../weblayer_instrumentation_test_M103/out/Release', + '--impl-version=103' ], 'identifier': 'with_impl_from_103', 'swarming': { @@ -479,23 +479,23 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M103', - 'revision': 'version:103.0.5060.30', + 'revision': 'version:103.0.5060.30' } - ], - }, + ] + } }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': { 'args': [ - '--webview-apk-path=apks/AOSP_SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--implementation-outdir', - '../../weblayer_instrumentation_test_M102/out/Release', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--impl-version=102', + '--webview-apk-path=apks/AOSP_SystemWebView.apk', + '--implementation-outdir', + '../../weblayer_instrumentation_test_M102/out/Release', + '--impl-version=102' ], 'identifier': 'with_impl_from_102', 'swarming': { @@ -503,10 +503,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.90', + 'revision': 'version:102.0.5005.90' } - ], - }, + ] + } }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ @@ -606,16 +606,16 @@ }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MILESTONE': { 'args': [ - '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--implementation-outdir', - '../../weblayer_instrumentation_test_M103/out/Release', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--impl-version=103', + '--webview-apk-path=apks/SystemWebView.apk', + '--implementation-outdir', + '../../weblayer_instrumentation_test_M103/out/Release', + '--impl-version=103' ], 'identifier': 'with_impl_from_103', 'swarming': { @@ -623,23 +623,23 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M103', - 'revision': 'version:103.0.5060.30', + 'revision': 'version:103.0.5060.30' } - ], - }, + ] + } }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': { 'args': [ - '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--implementation-outdir', - '../../weblayer_instrumentation_test_M102/out/Release', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--impl-version=102', + '--webview-apk-path=apks/SystemWebView.apk', + '--implementation-outdir', + '../../weblayer_instrumentation_test_M102/out/Release', + '--impl-version=102' ], 'identifier': 'with_impl_from_102', 'swarming': { @@ -647,10 +647,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.90', + 'revision': 'version:102.0.5005.90' } - ], - }, + ] + } }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ @@ -750,16 +750,16 @@ }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MILESTONE': { 'args': [ - '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', - '--client-outdir', - '../../weblayer_instrumentation_test_M103/out/Release', '--implementation-outdir', '.', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--client-version=103', + '--webview-apk-path=apks/SystemWebView.apk', + '--client-outdir', + '../../weblayer_instrumentation_test_M103/out/Release', + '--client-version=103' ], 'identifier': 'with_client_from_103', 'swarming': { @@ -767,23 +767,23 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M103', - 'revision': 'version:103.0.5060.30', + 'revision': 'version:103.0.5060.30' } - ], - }, + ] + } }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': { 'args': [ - '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', - '--client-outdir', - '../../weblayer_instrumentation_test_M102/out/Release', '--implementation-outdir', '.', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--client-version=102', + '--webview-apk-path=apks/SystemWebView.apk', + '--client-outdir', + '../../weblayer_instrumentation_test_M102/out/Release', + '--client-version=102' ], 'identifier': 'with_client_from_102', 'swarming': { @@ -791,10 +791,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M102', - 'revision': 'version:102.0.5005.90', + 'revision': 'version:102.0.5005.90' } - ], - }, + ] + } }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index fa19ac3..8bc8614 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -743,6 +743,22 @@ ] } ], + "AutofillAssistantCupVerification": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillAssistantSignGetActionsRequests", + "AutofillAssistantVerifyGetActionsResponses" + ] + } + ] + } + ], "AutofillAssistantDomAnnotation": [ { "platforms": [ @@ -1623,6 +1639,28 @@ ] } ], + "BackForwardCacheExtendTimeToLive": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "time_to_live_seconds": "600" + }, + "enable_features": [ + "BackForwardCacheTimeToLiveControl" + ] + } + ] + } + ], "BackForwardCacheMemoryControls": [ { "platforms": [ @@ -5195,25 +5233,6 @@ ] } ], - "MediaSessionPlaybackStateChangeBackForwardCache": [ - { - "platforms": [ - "android", - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "BackForwardCacheMediaSessionPlaybackStateChange" - ] - } - ] - } - ], "MeetDevicesMojoServices": [ { "platforms": [ @@ -9236,21 +9255,6 @@ ] } ], - "WebViewAppsPackageNamesAllowlist": [ - { - "platforms": [ - "android_webview" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "WebViewAppsPackageNamesAllowlist" - ] - } - ] - } - ], "WebViewLegacyTlsSupport": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index a87a0545..97263e9b5 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -968,9 +968,11 @@ kBackgroundTracingPerformanceMark_AllowList{ &kBackgroundTracingPerformanceMark, "allow_list", ""}; -// Controls whether the Sanitizer API is available. +// Controls whether (and how much of) the Sanitizer API is available. const base::Feature kSanitizerAPI{"SanitizerAPI", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSanitizerAPIv0{"SanitizerAPIv0", + base::FEATURE_DISABLED_BY_DEFAULT}; // Controls whether the Sanitizer API allows namespaced content (SVG + MathML). //
diff --git a/third_party/blink/common/privacy_budget/BUILD.gn b/third_party/blink/common/privacy_budget/BUILD.gn index 0e8611ce..35d2a792 100644 --- a/third_party/blink/common/privacy_budget/BUILD.gn +++ b/third_party/blink/common/privacy_budget/BUILD.gn
@@ -20,6 +20,7 @@ "identifiability_metrics.cc", "identifiability_sample_collector.cc", "identifiability_sample_collector_test_utils.h", + "identifiability_study_document_created.cc", "identifiability_study_settings.cc", "identifiable_token_builder.cc", ]
diff --git a/third_party/blink/common/privacy_budget/identifiability_study_document_created.cc b/third_party/blink/common/privacy_budget/identifiability_study_document_created.cc new file mode 100644 index 0000000..3881883 --- /dev/null +++ b/third_party/blink/common/privacy_budget/identifiability_study_document_created.cc
@@ -0,0 +1,80 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h" + +#include "services/metrics/public/cpp/metrics_export.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_source_id.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" + +namespace blink { + +IdentifiabilityStudyDocumentCreated::IdentifiabilityStudyDocumentCreated( + ukm::SourceIdObj source_id) + : source_id_(source_id.ToInt64()) {} + +IdentifiabilityStudyDocumentCreated::IdentifiabilityStudyDocumentCreated( + ukm::SourceId source_id) + : source_id_(source_id) {} + +IdentifiabilityStudyDocumentCreated::~IdentifiabilityStudyDocumentCreated() = + default; + +IdentifiabilityStudyDocumentCreated& +IdentifiabilityStudyDocumentCreated::SetNavigationSourceId( + ukm::SourceId navigation_source_id) { + navigation_source_id_ = navigation_source_id; + return *this; +} + +IdentifiabilityStudyDocumentCreated& +IdentifiabilityStudyDocumentCreated::SetIsMainFrame(bool is_main_frame) { + is_main_frame_ = is_main_frame; + return *this; +} + +IdentifiabilityStudyDocumentCreated& +IdentifiabilityStudyDocumentCreated::SetIsCrossSiteFrame( + bool is_cross_site_frame) { + is_cross_site_frame_ = is_cross_site_frame; + return *this; +} + +IdentifiabilityStudyDocumentCreated& +IdentifiabilityStudyDocumentCreated::SetIsCrossOriginFrame( + bool is_cross_origin_frame) { + is_cross_origin_frame_ = is_cross_origin_frame; + return *this; +} + +void IdentifiabilityStudyDocumentCreated::Record(ukm::UkmRecorder* recorder) { + using Metrics = blink::IdentifiableSurface::ReservedSurfaceMetrics; + base::flat_map<uint64_t, int64_t> metrics = { + {IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + Metrics::kDocumentCreated_IsCrossOriginFrame) + .ToUkmMetricHash(), + is_cross_origin_frame_}, + {IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + Metrics::kDocumentCreated_IsCrossSiteFrame) + .ToUkmMetricHash(), + is_cross_site_frame_}, + {IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + Metrics::kDocumentCreated_IsMainFrame) + .ToUkmMetricHash(), + is_main_frame_}, + {IdentifiableSurface::FromTypeAndToken( + blink::IdentifiableSurface::Type::kReservedInternal, + Metrics::kDocumentCreated_NavigationSourceId) + .ToUkmMetricHash(), + navigation_source_id_}}; + + recorder->AddEntry(ukm::mojom::UkmEntry::New( + source_id_, ukm::builders::Identifiability::kEntryNameHash, metrics)); +} + +} // namespace blink
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index c2a3d9f..c15df96 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -422,6 +422,7 @@ kBackgroundTracingPerformanceMark_AllowList; BLINK_COMMON_EXPORT extern const base::Feature kSanitizerAPI; +BLINK_COMMON_EXPORT extern const base::Feature kSanitizerAPIv0; BLINK_COMMON_EXPORT extern const base::Feature kSanitizerAPINamespaces; BLINK_COMMON_EXPORT extern const base::Feature kManagedConfiguration;
diff --git a/third_party/blink/public/common/privacy_budget/BUILD.gn b/third_party/blink/public/common/privacy_budget/BUILD.gn index 49a07de..1e0d6ea 100644 --- a/third_party/blink/public/common/privacy_budget/BUILD.gn +++ b/third_party/blink/public/common/privacy_budget/BUILD.gn
@@ -18,6 +18,7 @@ "identifiability_metric_builder.h", "identifiability_metrics.h", "identifiability_sample_collector.h", + "identifiability_study_document_created.h", "identifiability_study_settings.h", "identifiability_study_settings_provider.h", "identifiable_sample.h", @@ -30,6 +31,7 @@ ":internal", "//base", "//services/metrics/public/cpp:metrics_cpp", + "//services/metrics/public/cpp:ukm_builders", "//services/network/public/cpp:cpp", "//third_party/blink/public/common:common_export", "//third_party/blink/public/mojom:web_feature_mojo_bindings",
diff --git a/third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h b/third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h new file mode 100644 index 0000000..30dd9980 --- /dev/null +++ b/third_party/blink/public/common/privacy_budget/identifiability_study_document_created.h
@@ -0,0 +1,49 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_DOCUMENT_CREATED_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_DOCUMENT_CREATED_H_ + +#include "services/metrics/public/cpp/ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_source_id.h" +#include "third_party/blink/public/common/common_export.h" + +namespace blink { + +class BLINK_COMMON_EXPORT IdentifiabilityStudyDocumentCreated { + public: + // Construct an IdentifiabilityStudyDocumentCreated for the given |source_id|. + // The source must be known to UKM. + explicit IdentifiabilityStudyDocumentCreated(ukm::SourceIdObj source_id); + + // Same as previous constructor, but uses SourceId instead of SourceIdObj. + explicit IdentifiabilityStudyDocumentCreated(ukm::SourceId source_id); + + ~IdentifiabilityStudyDocumentCreated(); + + // Record collected metrics to `recorder`. + void Record(ukm::UkmRecorder* recorder); + + IdentifiabilityStudyDocumentCreated& SetNavigationSourceId( + ukm::SourceId navigation_source_id); + + IdentifiabilityStudyDocumentCreated& SetIsMainFrame(bool is_main_frame); + + IdentifiabilityStudyDocumentCreated& SetIsCrossOriginFrame( + bool is_cross_origin_frame); + + IdentifiabilityStudyDocumentCreated& SetIsCrossSiteFrame( + bool is_cross_site_frame); + + private: + const ukm::SourceId source_id_; + ukm::SourceId navigation_source_id_; + bool is_main_frame_; + bool is_cross_origin_frame_; + bool is_cross_site_frame_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_PRIVACY_BUDGET_IDENTIFIABILITY_STUDY_DOCUMENT_CREATED_H_
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h index a1eacf9..cd1f595 100644 --- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h +++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -10,7 +10,9 @@ #include <cstddef> #include <functional> #include <tuple> +#include <algorithm> +#include "services/metrics/public/cpp/ukm_builders.h" #include "third_party/blink/public/common/privacy_budget/identifiable_token.h" namespace blink { @@ -251,13 +253,31 @@ kMax = (1 << kTypeBits) - 1 }; + // These are metrics names of type 0 and are always reported when the study is + // enabled. + enum class ReservedSurfaceMetrics : uint64_t { + kDocumentCreated_IsCrossOriginFrame = 0, + kDocumentCreated_IsCrossSiteFrame = 1, + kDocumentCreated_IsMainFrame = 2, + kDocumentCreated_NavigationSourceId = 3, + kMax = kDocumentCreated_NavigationSourceId + }; + static_assert( + static_cast<uint64_t>(ReservedSurfaceMetrics::kMax) < + std::min( + ukm::builders::Identifiability::kGeneratorVersion_926NameHash, + ukm::builders::Identifiability::kStudyGeneration_626NameHash), + "All the ReservedSurfaceMetrics enum values should be strictly smaller " + "than kGeneratorVersion_926NameHash and kStudyGeneration_626NameHash to " + "avoid collisions."); + // HTML canvas readback -- bits [0-3] of the 64-bit input are the context type // (Type::kCanvasReadback), bits [4-6] are skipped ops, sensitive ops, and // partial image ops bits, respectively. The remaining bits are for the canvas // operations digest. If the digest wasn't calculated (there's no digest for // WebGL, for instance), the digest field is 0. enum CanvasTaintBit : uint64_t { - // At least one drawing operation didn't update the digest -- this is ether + // At least one drawing operation didn't update the digest -- this is either // due to performance or resource consumption reasons. kSkipped = UINT64_C(0x10),
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 2f1befd..a851381d 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -8248,7 +8248,6 @@ ContentMediaDevicesDispatcherHost ContentWebBluetooth ContentWebUSB - ContentMediaSession ContentMediaSessionService ContentScreenReader
diff --git a/third_party/blink/public/web/web_form_control_element.h b/third_party/blink/public/web/web_form_control_element.h index a25f9d9f..88404811 100644 --- a/third_party/blink/public/web/web_form_control_element.h +++ b/third_party/blink/public/web/web_form_control_element.h
@@ -87,8 +87,17 @@ // and make the option as the current selection. void SetValue(const WebString&, bool send_events = false); // Sets the autofilled value for input element, textarea element and select - // element and sends a sequence of events to the element. - void SetAutofillValue(const WebString&); + // element and sends a sequence of events to the element. The default + // parameter for the WebAutofillState will do the right thing (setting + // kAutofilled state if the value is non-null) except in two situations: + // - When resetting the state of <select> elements the state at page load, the + // passed value parameter is non-null and yet the select element should be + // in non-autofilled state. This is why the autofill state is only + // considered for <select> elements. + // - When filling a value from a <datalist> the field should not be labeled + // as autofilled. + void SetAutofillValue(const WebString&, + WebAutofillState = WebAutofillState::kAutofilled); // Triggers the emission of a focus event. void DispatchFocusEvent(); // Triggers the emission of a blur event.
diff --git a/third_party/blink/public/web/web_input_element.h b/third_party/blink/public/web/web_input_element.h index 6bd9f3d..7fa7456f 100644 --- a/third_party/blink/public/web/web_input_element.h +++ b/third_party/blink/public/web/web_input_element.h
@@ -72,7 +72,9 @@ int MaxLength() const; void SetActivatedSubmit(bool); int size() const; - void SetChecked(bool, bool send_events = false); + void SetChecked(bool, + bool send_events = false, + WebAutofillState = WebAutofillState::kNotFilled); // Sets the value inside the text field without being sanitized. Can't be // used if a renderer doesn't exist or on a non text field type. Caret will // be moved to the end.
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index c915d812..5f34f1f 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -822,7 +822,7 @@ std::move(decoder), loading_task_runner)), data_pipe_(std::move(data_pipe)), - script_url_string_(script_resource->Url().Copy().GetString()), + script_url_string_(script_resource->Url().GetString()), script_resource_identifier_(script_resource->InspectorId()), // Unfortunately there's no dummy encoding value in the enum; let's use // one we don't stream.
diff --git a/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc b/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc index 244872c..6bf5bad 100644 --- a/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc +++ b/third_party/blink/renderer/controller/performance_manager/v8_worker_memory_reporter.cc
@@ -105,8 +105,7 @@ memory_usage->bytes = bytes; if (worker_global_scope->IsUrlValid() && worker_global_scope->Url().GetString().length() < kMaxReportedUrlLength) { - // Copy the URL to send it over to the main thread. - memory_usage->url = worker_global_scope->Url().Copy(); + memory_usage->url = worker_global_scope->Url(); } NotifyMeasurementSuccess(std::move(memory_usage)); }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index 2067cf23..af17294 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -923,6 +923,8 @@ } bool DisplayLockContext::IsShapingDeferred() const { + if (!element_) + return false; if (const auto* layout_object = element_->GetLayoutObject()) return layout_object->IsShapingDeferred(); return false; @@ -1218,6 +1220,17 @@ !state(RenderAffectingState::kAutoUnlockedForPrint) && !state(RenderAffectingState::kSubtreeHasTopLayerElement))); + // For shaping-deferred boxes, we'd like to unlock permanently. + if (IsShapingDeferred() && state_ != EContentVisibility::kVisible && + !should_be_locked && IsLocked()) { + SetRequestedState(EContentVisibility::kVisible); + // We need to change the document lifecycle explicitly because Unlock() + // inside the above SetRequestedState() didn't change the lifecycle. + // See CanDirtyStyle() check in Unlock(). + document_->Lifecycle().EnsureStateAtMost(DocumentLifecycle::kStyleClean); + return; + } + if (should_be_locked && !IsLocked()) Lock(); else if (!should_be_locked && IsLocked())
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 37035de9..302fa7d 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -5775,8 +5775,7 @@ // we'll check both, in order to give warning messages that are more specific // about the cause. Note: this means the order of the checks is important. - if (RuntimeEnabledFeatures::CrossOriginIsolationEnabled() && - Agent::IsCrossOriginIsolated()) { + if (Agent::IsCrossOriginIsolated()) { AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::blink::ConsoleMessageSource::kSecurity, mojom::blink::ConsoleMessageLevel::kWarning,
diff --git a/third_party/blink/renderer/core/exported/web_form_control_element.cc b/third_party/blink/renderer/core/exported/web_form_control_element.cc index 4695583..ba623352 100644 --- a/third_party/blink/renderer/core/exported/web_form_control_element.cc +++ b/third_party/blink/renderer/core/exported/web_form_control_element.cc
@@ -178,14 +178,16 @@ nullptr, mojom::blink::FocusType::kForward, nullptr); } -void WebFormControlElement::SetAutofillValue(const WebString& value) { +void WebFormControlElement::SetAutofillValue(const WebString& value, + WebAutofillState autofill_state) { // The input and change events will be sent in setValue. if (IsA<HTMLInputElement>(*private_) || IsA<HTMLTextAreaElement>(*private_)) { if (!Focused()) DispatchFocusEvent(); Unwrap<Element>()->DispatchScopedEvent( *Event::CreateBubble(event_type_names::kKeydown)); - Unwrap<TextControlElement>()->SetAutofillValue(value); + Unwrap<TextControlElement>()->SetAutofillValue( + value, value.IsEmpty() ? WebAutofillState::kNotFilled : autofill_state); Unwrap<Element>()->DispatchScopedEvent( *Event::CreateBubble(event_type_names::kKeyup)); if (!Focused()) @@ -193,7 +195,7 @@ } else if (auto* select = ::blink::DynamicTo<HTMLSelectElement>(*private_)) { if (!Focused()) DispatchFocusEvent(); - select->SetValue(value, true); + select->SetAutofillValue(value, autofill_state); if (!Focused()) DispatchBlurEvent(); }
diff --git a/third_party/blink/renderer/core/exported/web_input_element.cc b/third_party/blink/renderer/core/exported/web_input_element.cc index e405b55..f3ec96b 100644 --- a/third_party/blink/renderer/core/exported/web_input_element.cc +++ b/third_party/blink/renderer/core/exported/web_input_element.cc
@@ -108,11 +108,14 @@ return ConstUnwrap<HTMLInputElement>()->IsValidValue(value); } -void WebInputElement::SetChecked(bool now_checked, bool send_events) { +void WebInputElement::SetChecked(bool now_checked, + bool send_events, + WebAutofillState autofill_state) { Unwrap<HTMLInputElement>()->setChecked( - now_checked, send_events - ? TextFieldEventBehavior::kDispatchInputAndChangeEvent - : TextFieldEventBehavior::kDispatchNoEvent); + now_checked, + send_events ? TextFieldEventBehavior::kDispatchInputAndChangeEvent + : TextFieldEventBehavior::kDispatchNoEvent, + autofill_state); } bool WebInputElement::IsChecked() const {
diff --git a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl index 58bd4608..34b0907 100644 --- a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl +++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
@@ -45,8 +45,7 @@ [CallWith=ScriptState] long setInterval(ScriptString handler, optional long timeout = 0, any... arguments); void clearInterval(optional long handle = 0); - [RuntimeEnabled=CrossOriginIsolation] - readonly attribute boolean crossOriginIsolated; + readonly attribute boolean crossOriginIsolated; [RuntimeEnabled=CoepReflection] readonly attribute DOMString crossOriginEmbedderPolicy;
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc index 4a73932..bfec761 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -1045,8 +1045,26 @@ return is_checked_; } +void HTMLInputElement::setCheckedForBinding(bool now_checked) { + if (GetAutofillState() != WebAutofillState::kAutofilled) { + setChecked(now_checked); + } else { + bool old_value = this->checked(); + setChecked(now_checked, TextFieldEventBehavior::kDispatchNoEvent, + old_value == now_checked ? WebAutofillState::kAutofilled + : WebAutofillState::kNotFilled); + if (Page* page = GetDocument().GetPage()) { + page->GetChromeClient().JavaScriptChangedAutofilledValue( + *this, old_value ? u"true" : u"false"); + } + } +} + void HTMLInputElement::setChecked(bool now_checked, - TextFieldEventBehavior event_behavior) { + TextFieldEventBehavior event_behavior, + WebAutofillState autofill_state) { + SetAutofillState(autofill_state); + dirty_checkedness_ = true; if (checked() == now_checked) return; @@ -1079,6 +1097,13 @@ DispatchInputEvent(); } + // We set the Autofilled state again because setting the autofill value + // triggers JavaScript events and the site may override the autofilled value, + // which resets the autofill state. Even if the website modifies the from + // control element's content during the autofill operation, we want the state + // to show as as autofilled. + SetAutofillState(autofill_state); + PseudoStateChanged(CSSSelector::kPseudoChecked); } @@ -1155,11 +1180,15 @@ if (!input_type_->CanSetSuggestedValue()) { // Clear the suggested value because it may have been set when // `input_type_->CanSetSuggestedValue()` was true. + SetAutofillState(WebAutofillState::kNotFilled); TextControlElement::SetSuggestedValue(String()); return; } needs_to_update_view_value_ = true; - TextControlElement::SetSuggestedValue(SanitizeValue(value)); + String sanitized_value = SanitizeValue(value); + SetAutofillState(sanitized_value.IsEmpty() ? WebAutofillState::kNotFilled + : WebAutofillState::kPreviewed); + TextControlElement::SetSuggestedValue(sanitized_value); SetNeedsStyleRecalc( kSubtreeStyleChange, StyleChangeReasonForTracing::Create(style_change_reason::kControlValue)); @@ -1192,12 +1221,15 @@ "to the empty string."); return; } - if (GetAutofillState() != WebAutofillState::kAutofilled) { SetValue(value); } else { String old_value = this->Value(); - SetValue(value); + SetValue(value, TextFieldEventBehavior::kDispatchNoEvent, + TextControlSetValueSelection::kSetSelectionToEnd, + old_value == value && !value.IsEmpty() + ? WebAutofillState::kAutofilled + : WebAutofillState::kNotFilled); if (Page* page = GetDocument().GetPage()) { page->GetChromeClient().JavaScriptChangedAutofilledValue(*this, old_value); @@ -1207,7 +1239,8 @@ void HTMLInputElement::SetValue(const String& value, TextFieldEventBehavior event_behavior, - TextControlSetValueSelection selection) { + TextControlSetValueSelection selection, + WebAutofillState autofill_state) { input_type_->WarnIfValueIsInvalidAndElementIsVisible(value); if (!input_type_->CanSetValue(value)) return; @@ -1216,28 +1249,37 @@ // update. TextControlElement::SetSuggestedValue(String()); - // Set autofilled to false, as the value might have been set by the website. - // If the field was autofilled, it'll be set to true from that method. - SetAutofillState(WebAutofillState::kNotFilled); + SetAutofillState(autofill_state); - EventQueueScope scope; - String sanitized_value = SanitizeValue(value); - bool value_changed = sanitized_value != this->Value(); + // Scope for EventQueueScope so that change events are dispatched and handled + // before the second SetAutofillState is executed. + { + EventQueueScope scope; + String sanitized_value = SanitizeValue(value); + bool value_changed = sanitized_value != this->Value(); - SetLastChangeWasNotUserEdit(); - needs_to_update_view_value_ = true; + SetLastChangeWasNotUserEdit(); + needs_to_update_view_value_ = true; - input_type_->SetValue(sanitized_value, value_changed, event_behavior, - selection); - input_type_view_->DidSetValue(sanitized_value, value_changed); + input_type_->SetValue(sanitized_value, value_changed, event_behavior, + selection); + input_type_view_->DidSetValue(sanitized_value, value_changed); - if (value_changed) { - NotifyFormStateChanged(); - if (sanitized_value.IsEmpty() && HasBeenPasswordField() && - GetDocument().GetPage()) { - GetDocument().GetPage()->GetChromeClient().PasswordFieldReset(*this); + if (value_changed) { + NotifyFormStateChanged(); + if (sanitized_value.IsEmpty() && HasBeenPasswordField() && + GetDocument().GetPage()) { + GetDocument().GetPage()->GetChromeClient().PasswordFieldReset(*this); + } } } + + // We set the Autofilled state again because setting the autofill value + // triggers JavaScript events and the site may override the autofilled value, + // which resets the autofill state. Even if the website modifies the from + // control element's content during the autofill operation, we want the state + // to show as as autofilled. + SetAutofillState(autofill_state); } void HTMLInputElement::SetNonAttributeValue(const String& sanitized_value) {
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h index 1452550..2ef83d48 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element.h +++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -114,10 +114,15 @@ bool HasBeenPasswordField() const; bool IsCheckable() const; + bool checkedForBinding() const { return checked(); } + void setCheckedForBinding(bool); + // TODO(crbug.com/1314360) Capitalize checked() and setChecked() because they + // are not called by v8 anymore. bool checked() const; void setChecked( bool, - TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent); + TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent, + WebAutofillState = WebAutofillState::kNotFilled); void DispatchChangeEventIfNeeded(); void DispatchInputAndChangeEventIfNeeded(); @@ -145,7 +150,8 @@ const String&, TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent, TextControlSetValueSelection = - TextControlSetValueSelection::kSetSelectionToEnd) override; + TextControlSetValueSelection::kSetSelectionToEnd, + WebAutofillState = WebAutofillState::kNotFilled) override; String valueForBinding() const { return Value(); } void setValueForBinding(const String&, ExceptionState&); void SetValueForUser(const String&); @@ -161,6 +167,9 @@ String LocalizeValue(const String&) const; + // Sets the suggested value and puts the element into + // WebAutofillState::kPreviewed state if |value| is non-empty, or + // WebAutofillState::kNotFilled otherwise. void SetSuggestedValue(const String& value) override; void SetEditingValue(const String&);
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.idl b/third_party/blink/renderer/core/html/forms/html_input_element.idl index ef1ddd0..b9b2a6e 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_input_element.idl
@@ -32,7 +32,7 @@ [CEReactions, Reflect] attribute DOMString alt; [CEReactions, ImplementedAs=IDLExposedAutofillValue] attribute DOMString autocomplete; [CEReactions, Reflect=checked] attribute boolean defaultChecked; - attribute boolean checked; + [ImplementedAs=checkedForBinding] attribute boolean checked; [CEReactions, Reflect] attribute DOMString dirName; [CEReactions, Reflect] attribute boolean disabled; [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 73ae0e9..c765124 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -103,7 +103,6 @@ last_on_change_option_(nullptr), is_multiple_(false), should_recalc_list_items_(false), - is_autofilled_by_preview_(false), index_to_select_on_cancel_(-1) { // Make sure SelectType is created after initializing |uses_menu_list_|. select_type_ = SelectType::Create(*this); @@ -288,7 +287,9 @@ SetValue(value); } else { String old_value = this->Value(); - SetValue(value); + SetValue(value, false, + value != old_value ? WebAutofillState::kNotFilled + : WebAutofillState::kAutofilled); if (Page* page = GetDocument().GetPage()) { page->GetChromeClient().JavaScriptChangedAutofilledValue(*this, old_value); @@ -296,7 +297,9 @@ } } -void HTMLSelectElement::SetValue(const String& value, bool send_events) { +void HTMLSelectElement::SetValue(const String& value, + bool send_events, + WebAutofillState autofill_state) { HTMLOptionElement* option = nullptr; // Find the option with value() matching the given parameter and make it the // current selection. @@ -309,17 +312,20 @@ HTMLOptionElement* previous_selected_option = SelectedOption(); SetSuggestedOption(nullptr); - if (is_autofilled_by_preview_) - SetAutofillState(WebAutofillState::kNotFilled); SelectOptionFlags flags = kDeselectOtherOptionsFlag | kMakeOptionDirtyFlag; if (send_events) flags |= kDispatchInputAndChangeEventFlag; - SelectOption(option, flags); + SelectOption(option, flags, autofill_state); if (send_events && previous_selected_option != option) select_type_->ListBoxOnChange(); } +void HTMLSelectElement::SetAutofillValue(const String& value, + WebAutofillState autofill_state) { + SetValue(value, true, autofill_state); +} + String HTMLSelectElement::SuggestedValue() const { return suggested_option_ ? suggested_option_->value() : ""; } @@ -333,7 +339,6 @@ for (auto* const option : GetOptionList()) { if (option->value() == value) { SetSuggestedOption(option); - is_autofilled_by_preview_ = true; return; } } @@ -704,6 +709,8 @@ void HTMLSelectElement::SetSuggestedOption(HTMLOptionElement* option) { if (suggested_option_ == option) return; + SetAutofillState(option ? WebAutofillState::kPreviewed + : WebAutofillState::kNotFilled); suggested_option_ = option; select_type_->DidSetSuggestedOption(option); @@ -824,14 +831,13 @@ // TODO(tkent): This function is not efficient. It contains multiple O(N) // operations. crbug.com/577989. void HTMLSelectElement::SelectOption(HTMLOptionElement* element, - SelectOptionFlags flags) { + SelectOptionFlags flags, + WebAutofillState autofill_state) { TRACE_EVENT0("blink", "HTMLSelectElement::selectOption"); bool should_update_popup = false; - // SelectedOption() is O(N). - if (IsAutofilled() && SelectedOption() != element) - SetAutofillState(WebAutofillState::kNotFilled); + SetAutofillState(element ? autofill_state : WebAutofillState::kNotFilled); if (element) { if (!element->Selected()) @@ -855,6 +861,13 @@ ->GetChromeClient() .DidChangeSelectionInSelectControl(*this); } + + // We set the Autofilled state again because setting the autofill value + // triggers JavaScript events and the site may override the autofilled value, + // which resets the autofill state. Even if the website modifies the from + // control element's content during the autofill operation, we want the state + // to show as as autofilled. + SetAutofillState(element ? autofill_state : WebAutofillState::kNotFilled); } void HTMLSelectElement::DispatchFocusEvent(
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index bd45a00..1a24b63 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -93,10 +93,20 @@ void remove(int index); String Value() const; - void SetValue(const String&, bool send_events = false); + void SetValue(const String&, + bool send_events = false, + WebAutofillState = WebAutofillState::kNotFilled); String valueForBinding() const { return Value(); } void setValueForBinding(const String&); + + // It is possible to pass WebAutofillState::kNotFilled here in case we need + // to simulate a reset of a <select> element. + void SetAutofillValue(const String& value, WebAutofillState); + String SuggestedValue() const; + // Sets the suggested value and puts the element into + // WebAutofillState::kPreviewed state if the value exists, or + // WebAutofillState::kNotFilled otherwise. void SetSuggestedValue(const String&); // |options| and |selectedOptions| are not safe to be used in in @@ -245,7 +255,9 @@ kMakeOptionDirtyFlag = 1 << 2, }; typedef unsigned SelectOptionFlags; - void SelectOption(HTMLOptionElement*, SelectOptionFlags); + void SelectOption(HTMLOptionElement*, + SelectOptionFlags, + WebAutofillState = WebAutofillState::kNotFilled); bool DeselectItemsWithoutValidation( HTMLOptionElement* element_to_exclude = nullptr); void ParseMultipleAttribute(const AtomicString&); @@ -289,7 +301,6 @@ bool uses_menu_list_ = true; bool is_multiple_; mutable bool should_recalc_list_items_; - bool is_autofilled_by_preview_; Member<SelectType> select_type_; int index_to_select_on_cancel_;
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc index 6e6b535..491091a 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -444,7 +444,10 @@ SetValue(value); } else { String old_value = this->Value(); - SetValue(value); + SetValue(value, TextFieldEventBehavior::kDispatchNoEvent, + TextControlSetValueSelection::kSetSelectionToEnd, + value != old_value ? WebAutofillState::kNotFilled + : WebAutofillState::kAutofilled); if (Page* page = GetDocument().GetPage()) { page->GetChromeClient().JavaScriptChangedAutofilledValue(*this, old_value); @@ -454,22 +457,24 @@ void HTMLTextAreaElement::SetValue(const String& value, TextFieldEventBehavior event_behavior, - TextControlSetValueSelection selection) { - SetValueCommon(value, event_behavior, selection); + TextControlSetValueSelection selection, + WebAutofillState autofill_state) { + SetValueCommon(value, event_behavior, selection, autofill_state); is_dirty_ = true; } void HTMLTextAreaElement::SetNonDirtyValue( const String& value, TextControlSetValueSelection selection) { - SetValueCommon(value, TextFieldEventBehavior::kDispatchNoEvent, selection); + SetValueCommon(value, TextFieldEventBehavior::kDispatchNoEvent, selection, + WebAutofillState::kNotFilled); is_dirty_ = false; } -void HTMLTextAreaElement::SetValueCommon( - const String& new_value, - TextFieldEventBehavior event_behavior, - TextControlSetValueSelection selection) { +void HTMLTextAreaElement::SetValueCommon(const String& new_value, + TextFieldEventBehavior event_behavior, + TextControlSetValueSelection selection, + WebAutofillState autofill_state) { // Code elsewhere normalizes line endings added by the user via the keyboard // or pasting. We normalize line endings coming from JavaScript here. String normalized_value = new_value; @@ -514,6 +519,7 @@ std::min(end_of_string, selection_end)); } + SetAutofillState(autofill_state); NotifyFormStateChanged(); switch (event_behavior) { case TextFieldEventBehavior::kDispatchChangeEvent: @@ -532,6 +538,13 @@ case TextFieldEventBehavior::kDispatchNoEvent: break; } + + // We set the Autofilled state again because setting the autofill value + // triggers JavaScript events and the site may override the autofilled value, + // which resets the autofill state. Even if the website modifies the from + // control element's content during the autofill operation, we want the state + // to show as as autofilled. + SetAutofillState(autofill_state); } String HTMLTextAreaElement::defaultValue() const { @@ -551,6 +564,8 @@ } void HTMLTextAreaElement::SetSuggestedValue(const String& value) { + SetAutofillState(!value.IsEmpty() ? WebAutofillState::kPreviewed + : WebAutofillState::kNotFilled); TextControlElement::SetSuggestedValue(value); SetNeedsStyleRecalc( kSubtreeStyleChange, @@ -712,7 +727,8 @@ const auto& source_element = To<HTMLTextAreaElement>(source); SetValueCommon(source_element.Value(), TextFieldEventBehavior::kDispatchNoEvent, - TextControlSetValueSelection::kSetSelectionToEnd); + TextControlSetValueSelection::kSetSelectionToEnd, + source_element.GetAutofillState()); is_dirty_ = source_element.is_dirty_; TextControlElement::CloneNonAttributePropertiesFrom(source, flag); }
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.h b/third_party/blink/renderer/core/html/forms/html_text_area_element.h index ba20a2c..a6e3560 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element.h +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
@@ -49,13 +49,17 @@ const String&, TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent, TextControlSetValueSelection = - TextControlSetValueSelection::kSetSelectionToEnd) override; + TextControlSetValueSelection::kSetSelectionToEnd, + WebAutofillState = WebAutofillState::kNotFilled) override; String valueForBinding() const { return Value(); } void setValueForBinding(const String&); String defaultValue() const; void setDefaultValue(const String&); int textLength() const { return Value().length(); } + // Sets the suggested value and puts the element into + // WebAutofillState::kPreviewed state if |value| is non-empty, or + // WebAutofillState::kNotFilled otherwise. void SetSuggestedValue(const String& value) override; // For ValidityState @@ -82,7 +86,8 @@ void SetNonDirtyValue(const String&, TextControlSetValueSelection); void SetValueCommon(const String&, TextFieldEventBehavior, - TextControlSetValueSelection); + TextControlSetValueSelection, + WebAutofillState autofill_state); bool IsPlaceholderVisible() const override { return is_placeholder_visible_; } void SetPlaceholderVisibility(bool) override;
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc index 2709e004..6847276 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -1048,11 +1048,14 @@ return "ltr"; } -void TextControlElement::SetAutofillValue(const String& value) { +void TextControlElement::SetAutofillValue(const String& value, + WebAutofillState autofill_state) { // Set the value trimmed to the max length of the field and dispatch the input // and change events. SetValue(value.Substring(0, maxLength()), - TextFieldEventBehavior::kDispatchInputAndChangeEvent); + TextFieldEventBehavior::kDispatchInputAndChangeEvent, + TextControlSetValueSelection::kSetSelectionToEnd, + value.IsEmpty() ? WebAutofillState::kNotFilled : autofill_state); } // TODO(crbug.com/772433): Create and use a new suggested-value element instead.
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.h b/third_party/blink/renderer/core/html/forms/text_control_element.h index af6e3d3..1a86c6f 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.h +++ b/third_party/blink/renderer/core/html/forms/text_control_element.h
@@ -126,7 +126,8 @@ const String&, TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent, TextControlSetValueSelection = - TextControlSetValueSelection::kSetSelectionToEnd) = 0; + TextControlSetValueSelection::kSetSelectionToEnd, + WebAutofillState = WebAutofillState::kNotFilled) = 0; TextControlInnerEditorElement* InnerEditorElement() const { return inner_editor_; @@ -144,8 +145,10 @@ String DirectionForFormData() const; // Set the value trimmed to the max length of the field and dispatch the input - // and change events. - void SetAutofillValue(const String& value); + // and change events. If |value| is empty, the autofill state is always + // set to WebAutofillState::kNotFilled. + void SetAutofillValue(const String& value, + WebAutofillState = WebAutofillState::kAutofilled); virtual void SetSuggestedValue(const String& value); const String& SuggestedValue() const;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index cba4e7a4..d9f284f 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -1090,7 +1090,7 @@ href_attribute->Value8BitIfNecessary())); bool is_valid_base_url = url.IsValid() && !url.ProtocolIsData() && !url.ProtocolIsJavaScript(); - predicted_base_element_url_ = is_valid_base_url ? url.Copy() : KURL(); + predicted_base_element_url_ = is_valid_base_url ? url : KURL(); } }
diff --git a/third_party/blink/renderer/core/layout/deferred_shaping_test.cc b/third_party/blink/renderer/core/layout/deferred_shaping_test.cc index 2e7a63c3..5813f0d 100644 --- a/third_party/blink/renderer/core/layout/deferred_shaping_test.cc +++ b/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/paint/paint_timing.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h" +#include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { @@ -158,6 +159,46 @@ EXPECT_TRUE(IsLocked("target")); } +TEST_F(DeferredShapingTest, NoAutoLock) { + SetBodyInnerHTML(R"HTML( +<div style="height:1800px"></div> +<div id="target">IFC</div> +)HTML"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_TRUE(IsDefer("target")); + EXPECT_TRUE(IsLocked("target")); + + auto* context = GetElementById("target")->GetDisplayLockContext(); + context->NotifySubtreeGainedSelection(); + EXPECT_FALSE(IsLocked("target")); + + context->NotifySubtreeLostSelection(); + EXPECT_FALSE(IsLocked("target")); +} + +// crbug.com/1330060 +TEST_F(DeferredShapingTest, NoAutoLockWithoutElement) { + SetBodyInnerHTML(R"HTML( +<div style="height:1800px"></div> +<div id="target">IFC</div> +)HTML"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_TRUE(IsDefer("target")); + EXPECT_TRUE(IsLocked("target")); + + Persistent<DisplayLockContext> context = + GetElementById("target")->GetDisplayLockContext(); + context->NotifySubtreeGainedSelection(); + EXPECT_FALSE(IsLocked("target")); + + GetElementById("target")->remove(); + UpdateAllLifecyclePhasesForTest(); + // Clear a WeakMember of DisplayLockContext. + ThreadState::Current()->CollectAllGarbageForTesting(); + context->NotifySubtreeLostSelection(); + // Pass if no crashes. +} + TEST_F(DeferredShapingTest, ListMarkerCrash) { SetBodyInnerHTML(R"HTML( <div style="height:1800px"></div>
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index c47759e..cb983012 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1216,7 +1216,7 @@ bool LayoutBox::HasOverrideIntrinsicContentWidth() const { NOT_DESTROYED(); - if (!ShouldApplySizeContainment()) + if (!ShouldApplyWidthContainment()) return false; return StyleRef().ContainIntrinsicWidth().has_value(); @@ -1224,7 +1224,7 @@ bool LayoutBox::HasOverrideIntrinsicContentHeight() const { NOT_DESTROYED(); - if (!ShouldApplySizeContainment()) + if (!ShouldApplyHeightContainment()) return false; return StyleRef().ContainIntrinsicHeight().has_value();
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index ed3969b..992cb3d 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -650,6 +650,16 @@ NOT_DESTROYED(); return StyleRef().ContainsBlockSize() && IsEligibleForSizeContainment(); } + inline bool ShouldApplyWidthContainment() const { + NOT_DESTROYED(); + return IsHorizontalWritingMode() ? ShouldApplyInlineSizeContainment() + : ShouldApplyBlockSizeContainment(); + } + inline bool ShouldApplyHeightContainment() const { + NOT_DESTROYED(); + return IsHorizontalWritingMode() ? ShouldApplyBlockSizeContainment() + : ShouldApplyInlineSizeContainment(); + } inline bool ShouldApplyStyleContainment() const { NOT_DESTROYED(); return StyleRef().ContainsStyle();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc index 98ad7055..4bc164f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -813,7 +813,7 @@ // Because children are already in the visual order, use LTR for the // fragment builder so that it should not transform the coordinates for RTL. - NGBoxFragmentBuilder box(item->GetLayoutObject(), &style, + NGBoxFragmentBuilder box(item->GetLayoutObject(), &style, space, {style.GetWritingMode(), TextDirection::kLtr}); box.SetInitialFragmentGeometry(fragment_geometry); box.SetBoxType(NGPhysicalFragment::kInlineBox);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc index 572c580..071bcd611 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -150,7 +150,7 @@ NGInlineChildLayoutContext context; NGBoxFragmentBuilder container_builder( - block_flow, block_flow->Style(), + block_flow, block_flow->Style(), constraint_space, block_flow->Style()->GetWritingDirection()); NGFragmentItemsBuilder items_builder(inline_node, container_builder.GetWritingDirection());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc index 106bfd29..da93f8d 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -55,10 +55,10 @@ PropagateChildData( child.layout_result->PhysicalFragment(), child.Offset() - - ComputeRelativeOffsetForInline(*ConstraintSpace(), + ComputeRelativeOffsetForInline(ConstraintSpace(), child.PhysicalFragment()->Style()), ComputeRelativeOffsetForOOFInInline( - *ConstraintSpace(), child.PhysicalFragment()->Style())); + ConstraintSpace(), child.PhysicalFragment()->Style())); // Skip over any children, the information should have already been // propagated into this layout result.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h index 9b098f09..875c676e 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -30,7 +30,7 @@ public: NGLineBoxFragmentBuilder(NGInlineNode node, scoped_refptr<const ComputedStyle> style, - const NGConstraintSpace* space, + const NGConstraintSpace& space, WritingDirectionMode writing_direction) : NGContainerFragmentBuilder( node,
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc index 3f213b8..7001029 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -287,7 +287,7 @@ NGBlockNode container_node(container); NGBoxFragmentBuilder container_builder( container_node, scoped_refptr<const ComputedStyle>(container_style), - /* space */ nullptr, container_style->GetWritingDirection()); + constraint_space, container_style->GetWritingDirection()); container_builder.SetIsNewFormattingContext( container_node.CreatesNewFormattingContext());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc index 69b36bd..94b07ae2 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
@@ -20,7 +20,7 @@ const NGBreakTokenVector* child_break_tokens = nullptr, bool has_seen_all_children = false) { NGBoxFragmentBuilder builder( - node, &node.Style(), /* space */ nullptr, + node, &node.Style(), NGConstraintSpace(), WritingDirectionMode(WritingMode::kHorizontalTb, TextDirection::kLtr)); DCHECK(!builder.HasBreakTokenData()); builder.SetBreakTokenData(MakeGarbageCollected<NGBlockBreakTokenData>());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index 3910c9f1..af4ffd0 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -1811,7 +1811,7 @@ box_->PaddingBefore(), box_->PaddingAfter()}; // TODO(kojii): Implement use_first_line_style. - NGBoxFragmentBuilder builder(*this, box_->Style(), &constraint_space, + NGBoxFragmentBuilder builder(*this, box_->Style(), constraint_space, {writing_mode, box_->StyleRef().Direction()}); builder.SetIsNewFormattingContext( constraint_space.IsNewFormattingContext());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index 9b0e4f6..c09e6f0 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -129,8 +129,7 @@ if (UNLIKELY(has_block_fragmentation_)) PropagateBreakInfo(*result_for_propagation, offset); - if (UNLIKELY(ConstraintSpace() && - ConstraintSpace()->ShouldPropagateChildBreakValues())) + if (UNLIKELY(ConstraintSpace().ShouldPropagateChildBreakValues())) PropagateChildBreakValues(*result_for_propagation, flex_column_break_after); } @@ -387,7 +386,7 @@ block_size_for_fragmentation_ = std::max(block_size_for_fragmentation_, block_end_in_container); - if (ConstraintSpace()->RequiresContentBeforeBreaking()) { + if (ConstraintSpace().RequiresContentBeforeBreaking()) { if (child_layout_result.IsBlockSizeForFragmentationClamped()) is_block_size_for_fragmentation_clamped_ = true; } @@ -415,7 +414,7 @@ // Downgrade the appeal of breaking inside this container, if the break // inside the child is less appealing than what we've found so far. NGBreakAppeal appeal_inside = - CalculateBreakAppealInside(*ConstraintSpace(), child_layout_result); + CalculateBreakAppealInside(ConstraintSpace(), child_layout_result); ClampBreakAppeal(appeal_inside); } @@ -431,7 +430,7 @@ // If a spanner was found inside the child, we need to finish up and propagate // the spanner to the column layout algorithm, so that it can take care of it. - if (UNLIKELY(ConstraintSpace()->IsInColumnBfc())) { + if (UNLIKELY(ConstraintSpace().IsInColumnBfc())) { if (const NGColumnSpannerPath* child_spanner_path = child_layout_result.ColumnSpannerPath()) { DCHECK(HasInflowChildBreakInside() || @@ -574,7 +573,7 @@ } void NGBoxFragmentBuilder::SetLastBaselineToBlockEndMarginEdgeIfNeeded() { - if (ConstraintSpace()->BaselineAlgorithmType() != + if (ConstraintSpace().BaselineAlgorithmType() != NGBaselineAlgorithmType::kInlineBlock) return; @@ -583,7 +582,7 @@ // When overflow is present (within an atomic-inline baseline context) we // should always use the block-end margin edge as the baseline. - NGBoxStrut margins = ComputeMarginsForSelf(*ConstraintSpace(), Style()); + NGBoxStrut margins = ComputeMarginsForSelf(ConstraintSpace(), Style()); SetLastBaseline(FragmentBlockSize() + margins.block_end); } @@ -669,8 +668,7 @@ DCHECK(!has_forced_break_); DCHECK(!HasBreakTokenData()); DCHECK_EQ(minimal_space_shortage_, kIndefiniteSize); - if (ConstraintSpace() && - !ConstraintSpace()->ShouldPropagateChildBreakValues()) { + if (!ConstraintSpace().ShouldPropagateChildBreakValues()) { DCHECK(!initial_break_before_); DCHECK_EQ(previous_break_after_, EBreakBetween::kAuto); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index 4c97178..2f91029 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -38,7 +38,7 @@ public: NGBoxFragmentBuilder(NGLayoutInputNode node, scoped_refptr<const ComputedStyle> style, - const NGConstraintSpace* space, + const NGConstraintSpace& space, WritingDirectionMode writing_direction) : NGContainerFragmentBuilder(node, std::move(style), @@ -51,10 +51,11 @@ // has NGInlineItem but does not have corresponding NGLayoutInputNode. NGBoxFragmentBuilder(LayoutObject* layout_object, scoped_refptr<const ComputedStyle> style, + const NGConstraintSpace& space, WritingDirectionMode writing_direction) : NGContainerFragmentBuilder(/* node */ nullptr, std::move(style), - /* space */ nullptr, + space, writing_direction), box_type_(NGPhysicalFragment::NGBoxType::kNormalBox), is_inline_formatting_context_(true) { @@ -73,9 +74,9 @@ border_padding_ + initial_fragment_geometry.scrollbar; original_border_scrollbar_padding_block_start_ = border_scrollbar_padding_.block_start; - if (space_) { + if (node_) { child_available_size_ = CalculateChildAvailableSize( - *space_, To<NGBlockNode>(node_), size_, border_scrollbar_padding_); + space_, To<NGBlockNode>(node_), size_, border_scrollbar_padding_); } } @@ -179,7 +180,6 @@ // its non-anonymous parent (similar to percentages). const LogicalSize& ChildAvailableSize() const { DCHECK(initial_fragment_geometry_); - DCHECK(space_); return child_available_size_; } const NGBlockNode& Node() { @@ -569,7 +569,7 @@ // Sets the last baseline for this fragment. void SetLastBaseline(LayoutUnit baseline) { - DCHECK_EQ(space_->BaselineAlgorithmType(), + DCHECK_EQ(space_.BaselineAlgorithmType(), NGBaselineAlgorithmType::kInlineBlock); last_baseline_ = baseline; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h index b8e39c8..6b016d3 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -341,7 +341,7 @@ has_descendant_that_depends_on_percentage_block_size_ = b; } - const NGConstraintSpace* ConstraintSpace() const { return space_; } + const NGConstraintSpace& ConstraintSpace() const { return space_; } const NGLayoutResult* Abort(NGLayoutResult::EStatus); @@ -356,7 +356,7 @@ NGContainerFragmentBuilder(NGLayoutInputNode node, scoped_refptr<const ComputedStyle> style, - const NGConstraintSpace* space, + const NGConstraintSpace& space, WritingDirectionMode writing_direction) : NGFragmentBuilder(std::move(style), writing_direction), node_(node), @@ -384,7 +384,7 @@ nullptr) const; NGLayoutInputNode node_; - const NGConstraintSpace* space_; + const NGConstraintSpace& space_; LayoutUnit bfc_line_offset_; absl::optional<LayoutUnit> bfc_block_offset_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc index 037548a9..169a27f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -1071,7 +1071,7 @@ const NGConstraintSpace& space, const NGFragmentGeometry& fragment_geometry) { const ComputedStyle* style = &multicol.Style(); - NGBoxFragmentBuilder multicol_container_builder(multicol, style, &space, + NGBoxFragmentBuilder multicol_container_builder(multicol, style, space, style->GetWritingDirection()); multicol_container_builder.SetIsNewFormattingContext(true); multicol_container_builder.SetInitialFragmentGeometry(fragment_geometry);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h index f6ab00a..97d7f0d 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
@@ -71,7 +71,7 @@ // currently performing block fragmentation; we also need to know if it has // already been fragmented (to resume layout correctly, but not break again). inline bool InvolvedInBlockFragmentation(const NGBoxFragmentBuilder& builder) { - return builder.ConstraintSpace()->HasBlockFragmentation() || + return builder.ConstraintSpace().HasBlockFragmentation() || IsResumingLayout(builder.PreviousBreakToken()); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h index 6c6378f2..2b602eb 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
@@ -81,7 +81,7 @@ break_token_(break_token), container_builder_(node, style, - &space, + space, {space.GetWritingMode(), direction}) {} // Constructor for algorithms that use NGBoxFragmentBuilder and @@ -93,7 +93,7 @@ container_builder_( params.node, ¶ms.node.Style(), - ¶ms.space, + params.space, {params.space.GetWritingMode(), params.space.Direction()}), additional_early_breaks_(params.additional_early_breaks) { container_builder_.SetIsNewFormattingContext( @@ -110,8 +110,7 @@ protected: const NGConstraintSpace& ConstraintSpace() const { - DCHECK(container_builder_.ConstraintSpace()); - return *container_builder_.ConstraintSpace(); + return container_builder_.ConstraintSpace(); } const ComputedStyle& Style() const { return node_.Style(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc index 26538cf..cd84c276 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
@@ -31,10 +31,6 @@ }; LayoutUnit intrinsic_block_size; unsigned bitfields[1]; - -#if DCHECK_IS_ON() - bool has_valid_space; -#endif }; ASSERT_SIZE(NGLayoutResult, SameSizeAsNGLayoutResult); @@ -95,8 +91,7 @@ } bitfields_.disable_simplified_layout = builder->disable_simplified_layout; - if (builder->ConstraintSpace() && - builder->ConstraintSpace()->ShouldPropagateChildBreakValues()) { + if (builder->ConstraintSpace().ShouldPropagateChildBreakValues()) { bitfields_.initial_break_before = static_cast<unsigned>( builder->initial_break_before_.value_or(EBreakBetween::kAuto)); bitfields_.final_break_after = @@ -188,10 +183,6 @@ if (new_end_margin_strut != NGMarginStrut() || HasRareData()) EnsureRareData()->end_margin_strut = new_end_margin_strut; - -#if DCHECK_IS_ON() - has_valid_space_ = other.has_valid_space_; -#endif } NGLayoutResult::NGLayoutResult(const NGLayoutResult& other, @@ -210,16 +201,11 @@ } DCHECK_EQ(physical_fragment_->Size(), other.physical_fragment_->Size()); - -#if DCHECK_IS_ON() - has_valid_space_ = other.has_valid_space_; -#endif } NGLayoutResult::NGLayoutResult(const NGPhysicalFragment* physical_fragment, NGContainerFragmentBuilder* builder) - : space_(builder->space_ ? NGConstraintSpace(*builder->space_) - : NGConstraintSpace()), + : space_(builder->space_), physical_fragment_(std::move(physical_fragment)), bitfields_(builder->is_self_collapsing_, builder->is_pushed_by_floats_, @@ -284,10 +270,6 @@ bitfields_.is_bfc_block_offset_nullopt = !builder->bfc_block_offset_.has_value(); } - -#if DCHECK_IS_ON() - has_valid_space_ = builder->space_; -#endif } NGExclusionSpace NGLayoutResult::MergeExclusionSpaces(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h index 288d5ac..dee9e42 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -421,9 +421,6 @@ // Returns the space which generated this object for caching purposes. const NGConstraintSpace& GetConstraintSpaceForCaching() const { -#if DCHECK_IS_ON() - DCHECK(has_valid_space_); -#endif return space_; } @@ -885,8 +882,7 @@ unsigned disable_simplified_layout : 1; }; - // The constraint space which generated this layout result, may not be valid - // as indicated by |has_valid_space_|. + // The constraint space which generated this layout result. const NGConstraintSpace space_; Member<const NGPhysicalFragment> physical_fragment_; @@ -910,10 +906,6 @@ LayoutUnit intrinsic_block_size_; Bitfields bitfields_; - -#if DCHECK_IS_ON() - bool has_valid_space_ = false; -#endif }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 86f406a..8544927 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -1306,7 +1306,7 @@ // The |fragmentainer_offset_delta| will not make a difference in the // initial column balancing pass. SetupSpaceBuilderForFragmentation( - *container_builder_->ConstraintSpace(), node, + container_builder_->ConstraintSpace(), node, /* fragmentainer_offset_delta */ LayoutUnit(), &builder, /* is_new_fc */ true, /* requires_content_before_breaking */ false); @@ -1361,9 +1361,8 @@ bool freeze_horizontal = false, freeze_vertical = false; // If we're in a measure pass, freeze both scrollbars right away, to avoid // quadratic time complexity for deeply nested flexboxes. - if (container_builder_->ConstraintSpace() && - container_builder_->ConstraintSpace()->CacheSlot() == - NGCacheSlot::kMeasure) + if (container_builder_->ConstraintSpace().CacheSlot() == + NGCacheSlot::kMeasure) freeze_horizontal = freeze_vertical = true; do { // Freeze any scrollbars that appeared, and relayout. Repeat until both @@ -1624,7 +1623,7 @@ /* is_new_fc */ true, requires_content_before_breaking); } else if (container_builder_->IsInitialColumnBalancingPass()) { SetupSpaceBuilderForFragmentation( - *container_builder_->ConstraintSpace(), node, block_offset, &builder, + container_builder_->ConstraintSpace(), node, block_offset, &builder, /* is_new_fc */ true, /* requires_content_before_breaking */ false); } @@ -1945,7 +1944,7 @@ // TODO(bebeaudr): Need to handle different fragmentation types. It won't // always be multi-column. return CreateConstraintSpaceForColumns( - *container_builder_->ConstraintSpace(), column_size, + container_builder_->ConstraintSpace(), column_size, percentage_resolution_size, allow_discard_start_margin, /* balance_columns */ false, min_break_appeal); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc index f2452911..3202c89 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -330,8 +330,7 @@ is_fieldset_container_ = builder->is_fieldset_container_; is_table_ng_part_ = builder->is_table_ng_part_; is_legacy_layout_root_ = builder->is_legacy_layout_root_; - is_painted_atomically_ = - builder->space_ && builder->space_->IsPaintedAtomically(); + is_painted_atomically_ = builder->space_.IsPaintedAtomically(); PhysicalBoxSides sides_to_include(builder->sides_to_include_, builder->GetWritingMode()); include_border_top_ = sides_to_include.top;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h b/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h index 6f2b33f5..3426f9ae 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h +++ b/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
@@ -63,7 +63,7 @@ String isolated_source_text = isolated_source_text_ ? isolated_source_text_.IsolatedCopy() : GetSourceText().ToString().IsolatedCopy(); - return ModuleScriptCreationParams(SourceURL().Copy(), BaseURL().Copy(), + return ModuleScriptCreationParams(SourceURL(), BaseURL(), source_location_type_, GetModuleType(), isolated_source_text); }
diff --git a/third_party/blink/renderer/core/loader/threadable_loader_test.cc b/third_party/blink/renderer/core/loader/threadable_loader_test.cc index b1634eb4..626aafd 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader_test.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader_test.cc
@@ -78,13 +78,13 @@ } KURL SuccessURL() { - return KURL("http://example.com/success").Copy(); + return KURL("http://example.com/success"); } KURL ErrorURL() { - return KURL("http://example.com/error").Copy(); + return KURL("http://example.com/error"); } KURL RedirectURL() { - return KURL("http://example.com/redirect").Copy(); + return KURL("http://example.com/redirect"); } void SetUpSuccessURL() {
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl_test.cc b/third_party/blink/renderer/core/page/chrome_client_impl_test.cc index 2b4085db..183eeb90 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl_test.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
@@ -29,6 +29,10 @@ */ #include "third_party/blink/renderer/core/page/chrome_client_impl.h" + +#include <string> +#include <vector> + #include "base/run_loop.h" #include "cc/trees/layer_tree_host.h" #include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h" @@ -51,8 +55,11 @@ #include "third_party/blink/renderer/core/html/forms/date_time_chooser_client.h" #include "third_party/blink/renderer/core/html/forms/file_chooser.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" +#include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/forms/html_select_element.h" +#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h" #include "third_party/blink/renderer/core/html/forms/mock_file_chooser.h" +#include "third_party/blink/renderer/core/html/forms/text_control_element.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/loader/frame_load_request.h" @@ -65,19 +72,24 @@ // To avoid conflicts with the CreateWindow macro from the Windows SDK... #undef CreateWindow +using ::testing::ElementsAre; +using ::testing::Eq; + namespace blink { namespace { class FakeChromeClientForAutofill : public EmptyChromeClient { public: - void JavaScriptChangedAutofilledValue(HTMLFormControlElement&, + void JavaScriptChangedAutofilledValue(HTMLFormControlElement& element, const String& old_value) override { - last_old_value_ = old_value; + last_notification_ = {element.GetIdAttribute().Utf8(), old_value.Utf8()}; } - const String& last_old_value() const { return last_old_value_; } + std::vector<std::string> GetAndResetLastEvent() { + return std::exchange(last_notification_, {}); + } private: - String last_old_value_; + std::vector<std::string> last_notification_; }; } // namespace @@ -403,48 +415,135 @@ Persistent<FakeChromeClientForAutofill> chrome_client_; }; -TEST_F(AutofillChromeClientTest, NotificationsOfJavaScriptChanges) { +// Validates the JavaScriptChangedAutofilledValue notification if JavaScript +// overrides the autofilled content of form controls *after* the fill has been +// concluded. +TEST_F(AutofillChromeClientTest, NotificationsOfJavaScriptChangesAfterFill) { SetHtmlInnerHTML(R"HTML( <!DOCTYPE HTML> <form id='form' method='GET' action='https://internal.test/' target='_blank'> - <input id='text' value='old_text'> - <textarea id='textarea'>old_textarea</textarea> + <input id='text'> + <textarea id='textarea'></textarea> <select id='select'> - <option value='select_a'>a</option> - <option value='select_b' selected>b</option> + <option value='initial' selected>a</option> + <option value='autofilled_select'>b</option> + <option value='overridden'>c</option> </select> - <selectmenu id='selectmenu'> - <option value='selectmenu_a'>a</option> - <option value='selectmenu_b' selected>b</option> - </select> - <input id='not_autofilled_text' value='old_text'> + <input id='not_autofilled_text'> </form> )HTML"); - for (const char* id : {"text", "textarea", "select", "selectmenu"}) { - To<HTMLFormControlElement>(GetElementById(id)) - ->SetAutofillState(WebAutofillState::kAutofilled); - } + auto* text_element = To<HTMLInputElement>(GetElementById("text")); + auto* textarea_element = To<HTMLTextAreaElement>(GetElementById("textarea")); + auto* select_element = To<HTMLSelectElement>(GetElementById("select")); + // HTMLSelectMenu does not support autofill, yet. + auto* not_autofilled_text = + To<HTMLInputElement>(GetElementById("not_autofilled_text")); + text_element->SetAutofillValue("autofilled_text"); + textarea_element->SetAutofillValue("autofilled_textarea"); + select_element->SetAutofillValue("autofilled_select", + WebAutofillState::kAutofilled); + + EXPECT_THAT(text_element->Value(), Eq("autofilled_text")); + EXPECT_THAT(text_element->GetAutofillState(), + Eq(WebAutofillState::kAutofilled)); ExecuteScript("document.getElementById('text').value = 'new_text';"); - EXPECT_EQ(String("old_text"), chrome_client_->last_old_value()); + EXPECT_THAT(text_element->Value(), Eq("new_text")); + EXPECT_THAT(text_element->GetAutofillState(), + Eq(WebAutofillState::kNotFilled)); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), + ::testing::ElementsAre("text", "autofilled_text")); + EXPECT_THAT(textarea_element->Value(), Eq("autofilled_textarea")); + EXPECT_THAT(textarea_element->GetAutofillState(), + Eq(WebAutofillState::kAutofilled)); ExecuteScript("document.getElementById('textarea').value = 'new_text';"); - EXPECT_EQ(String("old_textarea"), chrome_client_->last_old_value()); + EXPECT_THAT(textarea_element->Value(), Eq("new_text")); + EXPECT_THAT(textarea_element->GetAutofillState(), + Eq(WebAutofillState::kNotFilled)); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), + ::testing::ElementsAre("textarea", "autofilled_textarea")); - ExecuteScript("document.getElementById('select').value = 'select_a';"); - EXPECT_EQ(String("select_b"), chrome_client_->last_old_value()); - - ExecuteScript( - "document.getElementById('selectmenu').value = 'selectmenu_a';"); - EXPECT_EQ(String("selectmenu_b"), chrome_client_->last_old_value()); + EXPECT_THAT(select_element->Value(), Eq("autofilled_select")); + EXPECT_THAT(select_element->GetAutofillState(), + Eq(WebAutofillState::kAutofilled)); + ExecuteScript("document.getElementById('select').value = 'overridden';"); + EXPECT_THAT(select_element->Value(), Eq("overridden")); + EXPECT_THAT(select_element->GetAutofillState(), + Eq(WebAutofillState::kNotFilled)); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), + ::testing::ElementsAre("select", "autofilled_select")); // Because this is not in state "autofilled", the chrome client is not // informed about the change. + EXPECT_THAT(not_autofilled_text->Value().IsNull(), ::testing::IsTrue()); ExecuteScript( "document.getElementById('not_autofilled_text').value = 'new_text';"); - EXPECT_EQ(String("selectmenu_b"), chrome_client_->last_old_value()); + EXPECT_THAT(not_autofilled_text->Value(), Eq("new_text")); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), ::testing::ElementsAre()); +} + +// Validates the JavaScriptChangedAutofilledValue notification if JavaScript +// overrides the autofilled content of form controls during the fill operation. +// This is the case because a JavaScript event handler on change signals is +// is triggered during the autofill operation. +TEST_F(AutofillChromeClientTest, NotificationsOfJavaScriptChangesDuringFill) { + SetHtmlInnerHTML(R"HTML( + <!DOCTYPE HTML> + <form id='form' method='GET' action='https://internal.test/' + target='_blank'> + <input id='text'> + <textarea id='textarea'></textarea> + <select id='select'> + <option value='initial' selected>a</option> + <option value='autofilled_select'>b</option> + <option value='overridden'>c</option> + </select> + </form> + )HTML"); + + ExecuteScript(R"JS( + for (const id of ['text', 'textarea', 'select']) { + document.getElementById(id).addEventListener('change', () => { + document.getElementById(id).value = 'overridden'; + }); + } + )JS"); + + auto* text_element = To<HTMLInputElement>(GetElementById("text")); + auto* textarea_element = To<HTMLTextAreaElement>(GetElementById("textarea")); + auto* select_element = To<HTMLSelectElement>(GetElementById("select")); + // HTMLSelectMenu does not support autofill, yet. + text_element->SetAutofillValue("autofilled_text"); + EXPECT_THAT(text_element->Value(), Eq("overridden")); + // Note that we expect WebAutofillState::kAutofilled. This is a product + // decision: Even if the website messes with the content of the field after + // an autofill, we show is as autofilled. This applies only if the change + // via JavaScript happens instantaenously during the fill operation, not if + // JavaScript edits the value later. A common usecase is that we fill a + // credit card as a sequence of digits and the website inserts spaces to + // group the digits into blocks of four. + EXPECT_THAT(text_element->GetAutofillState(), + Eq(WebAutofillState::kAutofilled)); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), + ::testing::ElementsAre("text", "autofilled_text")); + + textarea_element->SetAutofillValue("autofilled_textarea"); + EXPECT_THAT(textarea_element->Value(), Eq("overridden")); + EXPECT_THAT(textarea_element->GetAutofillState(), + Eq(WebAutofillState::kAutofilled)); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), + ::testing::ElementsAre("textarea", "autofilled_textarea")); + + select_element->SetAutofillValue("autofilled_select", + WebAutofillState::kAutofilled); + EXPECT_THAT(select_element->Value(), Eq("overridden")); + EXPECT_THAT(select_element->GetAutofillState(), + Eq(WebAutofillState::kAutofilled)); + EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), + ::testing::ElementsAre("select", "autofilled_select")); } } // namespace blink
diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 index 6ef895fe..ac98ecc 100644 --- a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 +++ b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
@@ -201,7 +201,6 @@ { name: "CrossOriginIsolated", permissions_policy_name: "cross-origin-isolated", - depends_on: ["CrossOriginIsolation"], }, { name: "DirectSockets",
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 64c61250..1f59b6b 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -1790,15 +1790,12 @@ } if (auto* select = DynamicTo<HTMLSelectElement>(*element)) { - select->SetValue(value.IsEmpty() - ? String() // Null string resets the autofill state. - : value, - true /* send_events */); + select->SetAutofillValue( + value.IsEmpty() ? String() // Null string resets the autofill state. + : value, + value.IsEmpty() ? WebAutofillState::kNotFilled + : WebAutofillState::kAutofilled); } - - To<HTMLFormControlElement>(element)->SetAutofillState( - value.IsEmpty() ? WebAutofillState::kNotFilled - : blink::WebAutofillState::kAutofilled); } void Internals::setEditingValue(Element* element,
diff --git a/third_party/blink/renderer/core/workers/global_scope_creation_params.cc b/third_party/blink/renderer/core/workers/global_scope_creation_params.cc index 9dbf3e3..c8e0996 100644 --- a/third_party/blink/renderer/core/workers/global_scope_creation_params.cc +++ b/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
@@ -46,7 +46,7 @@ bool parent_cross_origin_isolated_capability, bool parent_direct_socket_capability, InterfaceRegistry* interface_registry) - : script_url(script_url.Copy()), + : script_url(script_url), script_type(script_type), global_scope_name(global_scope_name.IsolatedCopy()), user_agent(user_agent.IsolatedCopy()),
diff --git a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc index f2b8f09..8cb30130 100644 --- a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc +++ b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
@@ -66,7 +66,7 @@ const absl::optional<const blink::DedicatedWorkerToken>& token) { DCHECK(IsParentContextThread()); - KURL script_url = global_scope_creation_params->script_url.Copy(); + KURL script_url = global_scope_creation_params->script_url; if (global_scope_creation_params->web_worker_fetch_context) { global_scope_creation_params->web_worker_fetch_context
diff --git a/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc b/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc index a96f88e..879ecf8 100644 --- a/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc +++ b/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc
@@ -113,7 +113,7 @@ // Step 5: "Create an entry in cache with key url and value "fetching"." std::unique_ptr<Entry> entry = std::make_unique<Entry>(); entry->AddClient(client, client_task_runner); - entries_.insert(std::make_pair(url.Copy(), module_type), std::move(entry)); + entries_.insert(std::make_pair(url, module_type), std::move(entry)); // Step 6: "Fetch request." // Running the callback with an empty params will make the fetcher to fallback
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor_test.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor_test.cc index 75fc2d68..411d54a 100644 --- a/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor_test.cc +++ b/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor_test.cc
@@ -91,12 +91,22 @@ class MediaStreamTrackProcessorTest : public testing::Test { public: ~MediaStreamTrackProcessorTest() override { - platform_->RunUntilIdle(); + RunIOUntilIdle(); WebHeap::CollectAllGarbageForTesting(); } protected: ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + private: + void RunIOUntilIdle() const { + // Make sure that tasks on IO thread are completed before moving on. + base::RunLoop run_loop; + Platform::Current()->GetIOTaskRunner()->PostTaskAndReply( + FROM_HERE, base::BindOnce([] {}), run_loop.QuitClosure()); + run_loop.Run(); + base::RunLoop().RunUntilIdle(); + } }; TEST_F(MediaStreamTrackProcessorTest, VideoFramesAreExposed) {
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc index 9b01a5a..af1c4cc 100644 --- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc +++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -304,13 +304,10 @@ : mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent; return std::make_unique<CrossThreadFetchClientSettingsObjectData>( - script_url.Copy() /* global_object_url */, - script_url.Copy() /* base_url */, security_origin->IsolatedCopy(), - passed_settings_object.referrer_policy, - KURL::CreateIsolated( - passed_settings_object.outgoing_referrer.GetString()), - https_state, AllowedByNosniff::MimeTypeCheck::kLaxForWorker, - insecure_requests_policy, + script_url /* global_object_url */, script_url /* base_url */, + security_origin->IsolatedCopy(), passed_settings_object.referrer_policy, + KURL(passed_settings_object.outgoing_referrer.GetString()), https_state, + AllowedByNosniff::MimeTypeCheck::kLaxForWorker, insecure_requests_policy, FetchClientSettingsObject::InsecureNavigationsSet()); }
diff --git a/third_party/blink/renderer/modules/sanitizer_api/README.md b/third_party/blink/renderer/modules/sanitizer_api/README.md index 79d60973..034851d5 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/README.md +++ b/third_party/blink/renderer/modules/sanitizer_api/README.md
@@ -9,28 +9,47 @@ * --enable-experimental-web-platform-features or * chrome://flags#sanitizer-api -In Mozilla Firefox, the Sanitizer API can be enabled in about:config by setting -dom.security.sanitizer.enabled flag to true. - We are actively looking for feedback on the API. If you find problems or have suggestions for how the API should change, please read the available issues -at https://github.com/WICG/sanitizer-api/issues, and raise a new issue if your +at https://github.com/WICG/sanitizer-api/issues and raise a new issue if your suggestion isn't already covered. As this is a cross-browser effort, suggestions concerning the API should go to the standardisation group. Issues with Chromium's implementation should go to https://bugs.chromium.org and use the -[Blink > SecurityFeatures > SanitizerAPI component](https://bugs.chromium.org/p/chromium/issues/list?q=component%3ABlink%3ESecurityFeature%3ESanitizerAPI) +[Blink > SecurityFeatures > SanitizerAPI component](https://bugs.chromium.org/p/chromium/issues/list?q=component%3ABlink%3ESecurityFeature%3ESanitizerAPI). + +## Staged / Incremental Rollout + +The Sanitizer API is scheduled to be launched in stages. The API availability +can be controlled via flags: + +* `--enable-blink-features=SanitizerAPIv0`: This includes the basic Sanitizer + API with configuration and the `Element.setHTML` method, but not the + `.sanitizeFor` or `.sanitize` methods. +* `--enable-blink-features=SanitizerAPI`: This includes `SanitizerAPv0` + plus the sanitization methods of the `Sanitizer` object, as specified + as of 04/2022. These APIs are likely to change. + +The general `--enable-experimental-web-platform-features` flag implies the full +`--enable-blink-features=SanitizerAPI` feature set. ## Known Issues -The current implementation matches the specification as of 09/2021 and will be +The current implementation matches the specification as of 04/2022 and will be updated as the specification develops. Known omissions relative to the current spec are: -* [MathML and SVG are not currently supported](https://github.com/WICG/sanitizer-api/issues/103) +* Namespace support: Support for namespaced elements and attributes is + presently behind a separate flag, + `--enable-blink-features=SanitizerAPINamespacesForTesting`. The current + spec draft specifies the mechanism, but neither a default nor a baseline + configurations. The flag uses a temporary baseline list which has not yet + been vetted. -* [Element.setHTML signature now has an options dictionary.](https://github.com/WICG/sanitizer-api/issues/130) (M97) The previous method signature is supported but deprecated, and will be removed before enabling the Sanitizer by default. +* Secure context: The current spec draft requires a secure context. This + might change. Our implementation presently follows the draft. + ## Tests
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl index f9b4144..4648722 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl +++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl
@@ -5,13 +5,13 @@ // https://github.com/WICG/sanitizer-api [ - RuntimeEnabled=SanitizerAPI + RuntimeEnabled=SanitizerAPIv0 ] dictionary ElementSetHTMLOptions { Sanitizer sanitizer; }; [ - RuntimeEnabled=SanitizerAPI, + RuntimeEnabled=SanitizerAPIv0, ImplementedAs=ElementSanitizer ] partial interface Element { [CEReactions, RaisesException, CallWith=ScriptState, MeasureAs=SanitizerAPIElementSetSanitized] void setHTML(DOMString markup, optional ElementSetHTMLOptions options = {});
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl index a97bfcb8..ae0c520e 100644 --- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl +++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl
@@ -9,12 +9,13 @@ [ Exposed=Window, SecureContext, - RuntimeEnabled=SanitizerAPI + RuntimeEnabled=SanitizerAPIv0 ] interface Sanitizer { [MeasureAs=SanitizerAPICreated, CallWith=ExecutionContext, RaisesException] constructor(optional SanitizerConfig config = {}); - [MeasureAs=SanitizerAPIToFragment, CallWith=ScriptState, RaisesException] DocumentFragment sanitize(SanitizerInput input); - [MeasureAs=SanitizerAPISanitizeFor, CallWith=ScriptState, RaisesException] Element? sanitizeFor(DOMString element, DOMString markup); + [MeasureAs=SanitizerAPIToFragment, RuntimeEnabled=SanitizerAPI, +CallWith=ScriptState, RaisesException] DocumentFragment sanitize(SanitizerInput input); + [MeasureAs=SanitizerAPISanitizeFor, RuntimeEnabled=SanitizerAPI, CallWith=ScriptState, RaisesException] Element? sanitizeFor(DOMString element, DOMString markup); [MeasureAs=SanitizerAPIGetConfig] SanitizerConfig getConfiguration(); [MeasureAs=SanitizerAPIGetDefaultConfig] static SanitizerConfig getDefaultConfiguration();
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc b/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc index 036facd..9569803 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
@@ -274,7 +274,7 @@ // worker thread later, so they should keep isolated from the current thread. for (const WebURL& url : installed_scripts_manager_params->installed_scripts_urls) { - installed_urls_.insert(KURL(url).Copy()); + installed_urls_.insert(KURL(url)); } PostCrossThreadTask(
diff --git a/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc b/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc index 1d6e20c9..a020f76 100644 --- a/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc +++ b/third_party/blink/renderer/modules/service_worker/web_service_worker_fetch_context_impl.cc
@@ -37,14 +37,11 @@ mojom::blink::SubresourceLoaderUpdaterInterfaceBase> pending_subresource_loader_updater, const WebVector<WebString>& cors_exempt_header_list) { - // Create isolated copies for `worker_script_url` and - // `script_url_to_skip_throttling` as the fetch context will be used on a - // service worker thread that is different from the current thread. return base::MakeRefCounted<WebServiceWorkerFetchContextImpl>( - renderer_preferences, KURL::CreateIsolated(worker_script_url.GetString()), + renderer_preferences, KURL(worker_script_url.GetString()), std::move(pending_url_loader_factory), std::move(pending_script_loader_factory), - KURL::CreateIsolated(script_url_to_skip_throttling.GetString()), + KURL(script_url_to_skip_throttling.GetString()), std::move(throttle_provider), std::move(websocket_handshake_throttle_provider), std::move(preference_watcher_receiver),
diff --git a/third_party/blink/renderer/platform/blob/blob_url.cc b/third_party/blink/renderer/platform/blob/blob_url.cc index 08d382a8..5cc5c2f 100644 --- a/third_party/blink/renderer/platform/blob/blob_url.cc +++ b/third_party/blink/renderer/platform/blob/blob_url.cc
@@ -56,7 +56,7 @@ DCHECK(!origin_string.IsEmpty()); String url_string = "blob:" + origin_string + '/' + WTF::CreateCanonicalUUIDString(); - return KURL::CreateIsolated(url_string); + return KURL(url_string); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc index 0b9998c..e4fb5e6 100644 --- a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc +++ b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
@@ -44,7 +44,7 @@ ContextProviderCreationInfo creation_info; creation_info.context_attributes = context_attributes; creation_info.gl_info = gl_info; - creation_info.url = url.Copy(); + creation_info.url = url; PostCrossThreadTask( *Thread::MainThread()->GetTaskRunner(), FROM_HERE, CrossThreadBindOnce(&CreateContextProviderOnMainThread,
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h b/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h index 062553d..68c9f5d 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
@@ -128,9 +128,8 @@ // Gets a copy of the data suitable for passing to another thread. std::unique_ptr<CrossThreadFetchClientSettingsObjectData> CopyData() const { return std::make_unique<CrossThreadFetchClientSettingsObjectData>( - global_object_url_.Copy(), base_url_.Copy(), - security_origin_->IsolatedCopy(), referrer_policy_, - outgoing_referrer_.IsolatedCopy(), https_state_, + global_object_url_, base_url_, security_origin_->IsolatedCopy(), + referrer_policy_, outgoing_referrer_.IsolatedCopy(), https_state_, mime_type_check_for_classic_worker_script_, insecure_requests_policy_, insecure_navigations_set_); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index cf5de846..810de618 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -480,10 +480,6 @@ name: "CorsRFC1918", }, { - name: "CrossOriginIsolation", - status: "stable", - }, - { name: "CrossOriginOpenerPolicyReporting", origin_trial_feature_name: "CrossOriginOpenerPolicyReporting", origin_trial_allows_third_party: true, @@ -2060,6 +2056,12 @@ name: "SanitizerAPI", status: "experimental", }, + { + name: "SanitizerAPIv0", + status: "experimental", + implied_by: ["SanitizerAPI"], + }, + // WebSpeech API with both speech recognition and synthesis functionality // is not fully enabled on all platforms. {
diff --git a/third_party/blink/renderer/platform/weborigin/kurl.cc b/third_party/blink/renderer/platform/weborigin/kurl.cc index 87eb3cf..3de23a6 100644 --- a/third_party/blink/renderer/platform/weborigin/kurl.cc +++ b/third_party/blink/renderer/platform/weborigin/kurl.cc
@@ -247,12 +247,6 @@ nullptr /* query_encoding */); } -KURL KURL::CreateIsolated(const String& url) { - // FIXME: We should be able to skip this extra copy and created an - // isolated KURL more efficiently. - return KURL(url).Copy(); -} - // Constructs a new URL given a base URL and a possibly relative input URL. // This assumes UTF-8 encoding. KURL::KURL(const KURL& base, const String& relative) { @@ -285,7 +279,7 @@ parsed_(other.parsed_), string_(other.string_) { if (other.inner_url_.get()) - inner_url_ = std::make_unique<KURL>(other.inner_url_->Copy()); + inner_url_ = std::make_unique<KURL>(*other.inner_url_); } KURL::~KURL() = default; @@ -297,24 +291,12 @@ parsed_ = other.parsed_; string_ = other.string_; if (other.inner_url_) - inner_url_ = std::make_unique<KURL>(other.inner_url_->Copy()); + inner_url_ = std::make_unique<KURL>(*other.inner_url_); else inner_url_.reset(); return *this; } -KURL KURL::Copy() const { - KURL result; - result.is_valid_ = is_valid_; - result.protocol_is_in_http_family_ = protocol_is_in_http_family_; - result.protocol_ = protocol_.IsolatedCopy(); - result.parsed_ = parsed_; - result.string_ = string_.IsolatedCopy(); - if (inner_url_) - result.inner_url_ = std::make_unique<KURL>(inner_url_->Copy()); - return result; -} - bool KURL::IsNull() const { return string_.IsNull(); }
diff --git a/third_party/blink/renderer/platform/weborigin/kurl.h b/third_party/blink/renderer/platform/weborigin/kurl.h index 2210036..68a4ddf 100644 --- a/third_party/blink/renderer/platform/weborigin/kurl.h +++ b/third_party/blink/renderer/platform/weborigin/kurl.h
@@ -95,9 +95,6 @@ // saving outweigh the possible slow-downs. explicit KURL(const String&); - // Creates an isolated URL object suitable for sending to another thread. - static KURL CreateIsolated(const String&); - // Resolves the relative URL with the given base URL. If provided, the // TextEncoding is used to encode non-ASCII characters. The base URL can be // null or empty, in which case the relative URL will be interpreted as @@ -123,11 +120,6 @@ // base of null or the empty string gives the same result as the // standard String constructor. - // Makes a deep copy. Helpful only if you need to use a KURL on another - // thread. Since the underlying StringImpl objects are immutable, there's - // no other reason to ever prefer copy() over plain old assignment. - KURL Copy() const; - bool IsNull() const; bool IsEmpty() const; bool IsValid() const; @@ -264,8 +256,7 @@ bool protocol_is_in_http_family_; // Keep a separate string for the protocol to avoid copious copies for - // protocol(). Normally this will be Atomic, except when constructed via - // KURL::copy(), which is deep. + // protocol(). String protocol_; url::Parsed parsed_; @@ -328,10 +319,9 @@ }; template <> -struct CrossThreadCopier<blink::KURL> { +struct CrossThreadCopier<blink::KURL> + : public CrossThreadCopierPassThrough<blink::KURL> { STATIC_ONLY(CrossThreadCopier); - typedef blink::KURL Type; - static Type Copy(const blink::KURL& url) { return url.Copy(); } }; } // namespace WTF
diff --git a/third_party/blink/renderer/platform/weborigin/kurl_test.cc b/third_party/blink/renderer/platform/weborigin/kurl_test.cc index d879ba6..a7a9e4e 100644 --- a/third_party/blink/renderer/platform/weborigin/kurl_test.cc +++ b/third_party/blink/renderer/platform/weborigin/kurl_test.cc
@@ -754,26 +754,13 @@ EXPECT_EQ(11u, kurl3.PathAfterLastSlash()); } -TEST(KURLTest, DeepCopy) { - const char kUrl[] = "http://www.google.com/"; - const KURL src(kUrl); - EXPECT_TRUE(src.GetString() == - kUrl); // This really just initializes the cache. - const KURL dest = src.Copy(); - EXPECT_TRUE(dest.GetString() == - kUrl); // This really just initializes the cache. - - // The pointers should be different for both UTF-8 and UTF-16. - EXPECT_NE(dest.GetString().Impl(), src.GetString().Impl()); -} - TEST(KURLTest, DeepCopyInnerURL) { const char kUrl[] = "filesystem:http://www.google.com/temporary/test.txt"; const char kInnerURL[] = "http://www.google.com/temporary"; const KURL src(kUrl); EXPECT_TRUE(src.GetString() == kUrl); EXPECT_TRUE(src.InnerURL()->GetString() == kInnerURL); - const KURL dest = src.Copy(); + const KURL dest = src; EXPECT_TRUE(dest.GetString() == kUrl); EXPECT_TRUE(dest.InnerURL()->GetString() == kInnerURL); }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index cc7a66b..22a73d3 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -258,6 +258,7 @@ # These tests are flaky with BFCache, which is enabled by default. crbug.com/1171298 virtual/plz-dedicated-worker/http/tests/inspector-protocol/network/interception-download.js [ Failure Pass ] +crbug.com/1311546 http/tests/test-runner/back-forward.html [ Failure Pass ] # These tests require LazyEmbed, which is currently disabled by default. crbug.com/1247131 virtual/automatic-lazy-frame-loading/wpt_internal/lazyembed/* [ Pass ] @@ -1881,7 +1882,6 @@ # @container / contain:inline-size crbug.com/1294155 external/wpt/css/css-contain/container-queries/canvas-as-container-004.html [ Failure ] crbug.com/1307656 external/wpt/css/css-contain/container-queries/crashtests/columns-in-table-002-crash.html [ Crash ] -crbug.com/1328066 external/wpt/css/css-contain/contain-inline-size-intrinsic.html [ Failure ] # CSS Scrollbars crbug.com/891944 external/wpt/css/css-scrollbars/textarea-scrollbar-width-none.html [ Failure ] @@ -6994,9 +6994,6 @@ # Sheriff 2022-05-11 crbug.com/1324428 fast/webgl/canvas-toDataURL-crash.html [ Crash Pass ] -# Disabled to allow a DevTools roll -crbug.com/1325751 http/tests/devtools/extensions/extensions-api.js [ Failure Pass ] - # Throttling a hidden-cross origin frame may stall animations. crbug.com/1323246 external/wpt/web-animations/timing-model/timelines/sibling-iframe-timeline.html [ Failure Pass ] @@ -7019,3 +7016,6 @@ crbug.com/1325307 fast/css-grid-layout/grid-auto-repeat-huge-grid-003.html [ Skip ] crbug.com/1325307 fast/css-grid-layout/grid-auto-repeat-huge-grid-009.html [ Skip ] crbug.com/1325307 fast/css-grid-layout/grid-auto-repeat-huge-grid-010.html [ Skip ] + +# Sheriff 2022-05-30 +crbug.com/1330238 [ Mac ] http/tests/devtools/elements/styles-3/styles-computed-trace.js [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version index 8c69cb0..4886192 100644 --- a/third_party/blink/web_tests/external/Version +++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@ -Version: 8fadb381209a215280dc3ad96d0f135b6005f176 +Version: 0a72bfc95905c163a65401318b8914e18b8f764f
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 d601bff..b59decc 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
@@ -371145,7 +371145,7 @@ ] ], "system-color-compute.html": [ - "49c61647777ef2136128547fddea068745b2fe49", + "fffc368f4eb75dbeb741d0426dcd65d634493349", [ null, {} @@ -398327,7 +398327,7 @@ ] ], "parse-has.html": [ - "219a6c9f0bd99e238fda7e98fa800fcb9c38311f", + "e7d4ab6a32136e1a8a1ecb4f961ca5ce5f1aeb78", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color/system-color-compute.html b/third_party/blink/web_tests/external/wpt/css/css-color/system-color-compute.html index 49c6164..fffc368 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color/system-color-compute.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color/system-color-compute.html
@@ -99,13 +99,13 @@ let inherited_value = getComputedStyle(document.getElementById("inherited")) .getPropertyValue(property); - assert_equals(inherited_value, specified_value); - }, "System color computes to itself on " + property); + assert_not_equals(inherited_value, specified_value); + }, "System color doesn't compute to itself on " + property); test(function() { let inherited_value = document.getElementById("inherited").computedStyleMap() .get(property); - assert_regexp_match(inherited_value, /menu/i); + assert_false(/menu/i.test(inherited_value)); }, "Inherited system color keyword is observable on " + property); } </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/host-pseudo-class-in-has.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/host-pseudo-class-in-has.html new file mode 100644 index 0000000..a2c63d5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/host-pseudo-class-in-has.html
@@ -0,0 +1,65 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: Invalidation for :host() and :host-context() inside :has()</title> +<link rel="author" title="Byungwoo" href="mailto:blee@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/selectors/#relational"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="host_parent"><div id="host"></div></div> +<script> + var shadow = host.attachShadow({ mode: 'open' }); + shadow.innerHTML = ` + <style> + .subject { + color: red; + } + .subject:has(:is(:host-context(.a) > .foo .bar)) { color: green } + .subject:has(:is(:host(.a) > .foo .bar)) { color: yellowgreen } + .subject:has(:is(:host-context(.a) .bar)) { color: blue } + .subject:has(:is(:host(.a) .bar)) { color: skyblue } + </style> + <div class="foo"> + <div id="subject1" class="subject"> + <div class="bar"></div> + </div> + </div> + <div> + <div class="foo"> + <div id="subject2" class="subject"> + <div class="bar"></div> + </div> + </div> + </div> + `; + + const red = "rgb(255, 0, 0)"; + const green = "rgb(0, 128, 0)"; + const yellowgreen = "rgb(154, 205, 50)"; + const blue = "rgb(0, 0, 255)"; + const skyblue = "rgb(135, 206, 235)"; + + function checkColor(test_name, subject_id, subject_color) { + test(function() { + let subject = shadow.querySelector("#" + subject_id); + assert_equals(getComputedStyle(subject).color, subject_color); + }, test_name + ": Check #" + subject_id + " color"); + } + + checkColor("Before adding 'a' to #host_parent", "subject1", red); + checkColor("Before adding 'a' to #host_parent", "subject2", red); + + host_parent.classList.add('a'); + + checkColor("After adding 'a' to #host_parent", "subject1", green); + checkColor("After adding 'a' to #host_parent", "subject2", blue); + + host_parent.classList.remove('a'); + + checkColor("After removing 'a' from #host_parent", "subject1", red); + checkColor("After removing 'a' from #host_parent", "subject2", red); + + host.classList.add('a'); + + checkColor("After adding 'a' to #host", "subject1", yellowgreen); + checkColor("After adding 'a' to #host", "subject2", skyblue); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has.html index 4b0225eb..4e6d4c8 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has.html +++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has.html
@@ -7,115 +7,373 @@ <script src="/resources/testharnessreport.js"></script> <style> div { color: grey } -.red:has(#descendant:is(.a .b)) { color: red } -.green:has(#descendant:is(.c ~ .d .e)) { color: green } -.blue:has(~ #indirect_next:is(.f ~ .g)) { color: blue } -.yellow:has(~ #indirect_next:is(.h .i)) { color: yellow } -.purple:has(~ #indirect_next:is(.j ~ .k .l)) { color: purple } +.red:has(#descendant:is(.a_has_scope .b)) { color: red } +.orangered:has(#descendant:is(.a_descendant .b)) #descendant { color: orangered } +.darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next { color: darkred } +.pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child { color: pink } +.green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) { color: green } +.lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant { color: lightgreen } +.darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next { color: darkgreen } +.yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child { color: yellowgreen } +.blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) { color: blue } +.skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant { color: skyblue } +.lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next { color: lightblue } +.darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child { color: darkblue } +.yellow:has(~ #indirect_next:is(.h_has_scope .i)) { color: yellow } +.ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant { color: ivory } +.greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next { color: greenyellow } +.khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child { color: khaki } +.purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) { color: purple } +.violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant { color: violet } +.orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next { color: orchid } +.plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child { color: plum } .orange:has(#descendant:is(:is(.m, .n) .o)) { color: orange } </style> <div> + <div class="p"></div> <div id="parent_previous"></div> <div id="parent" class="d k"> + <div class="p"></div> <div id="previous"></div> + <div class="p"></div> <div id="has_scope" class="d"> + <div class="p"></div> <div id="child_previous"></div> <div id="child" class="d"> <div id="descendant" class="b e o"></div> </div> </div> + <div class="p"></div> <div id="direct_next"></div> - <div id="indirect_next" class="g i l"></div> + <div id="indirect_next" class="g i l"> + <div id="indirect_next_child"></div> + </div> </div> </div> <script> const grey = "rgb(128, 128, 128)"; const red = "rgb(255, 0, 0)"; +const orangered = "rgb(255, 69, 0)"; +const darkred = "rgb(139, 0, 0)"; +const pink = "rgb(255, 192, 203)"; const green = "rgb(0, 128, 0)"; +const lightgreen = "rgb(144, 238, 144)"; +const darkgreen = "rgb(0, 100, 0)"; +const yellowgreen = "rgb(154, 205, 50)"; const blue = "rgb(0, 0, 255)"; +const skyblue = "rgb(135, 206, 235)"; +const lightblue = "rgb(173, 216, 230)"; +const darkblue = "rgb(0, 0, 139)"; const yellow = "rgb(255, 255, 0)"; +const ivory = "rgb(255, 255, 240)"; +const greenyellow = "rgb(173, 255, 47)"; +const khaki = "rgb(240, 230, 140)"; const purple = "rgb(128, 0, 128)"; +const violet = "rgb(238, 130, 238)"; +const orchid = "rgb(218, 112, 214)"; +const plum = "rgb(221, 160, 221)"; const orange = "rgb(255, 165, 0)"; -function changeAndTest(operation, class_name, element_id, - selector, matches_result, scope_color) { +function addClass(element, class_name) { + element.classList.add(class_name); +} + +function removeClass(element, class_name) { + element.classList.remove(class_name); +} + +function testClassChange(operation, class_name, element_id, + selector, matches_result, + subject_id, subject_color) { let element = document.getElementById(element_id); assert_equals(element ? element.id : "", element_id); + let subject = document.getElementById(subject_id); + assert_equals(subject ? subject.id : "", subject_id); let message_prefix = [ "[", selector, "]", - ["#", element.id, ".classList.", operation, "('", class_name, "')"].join(""), + ["#", element.id, ".classList.", + (operation == addClass ? "add" : "remove"), + "('", class_name, "')"].join(""), ": "].join(" "); - if (operation == "add") { - element.classList.add(class_name); - } else { - assert_equals(operation, "remove"); - element.classList.remove(class_name); - } + operation(element, class_name); test(function() { - assert_equals(has_scope.matches(selector), matches_result); + assert_equals(subject.matches(selector), matches_result); }, message_prefix + "check matches (" + matches_result + ")"); test(function() { - assert_equals(getComputedStyle(has_scope).color, scope_color); - }, message_prefix + "check #has_scope color"); + assert_equals(getComputedStyle(subject).color, subject_color); + }, message_prefix + "check #" + subject_id + " color"); +} + +function testSiblingInsertionRemoval(class_name, insert_before_id, selector, + subject_id, + insertion_matches_result, + insertion_subject_color, + removal_matches_result, + removal_subject_color) { + let insert_before = document.getElementById(insert_before_id); + assert_equals(insert_before ? insert_before.id : "", insert_before_id); + let parent = insert_before.parentElement; + let subject = document.getElementById(subject_id); + assert_equals(subject ? subject.id : "", subject_id); + let message_prefix = [ + "[", selector, "]", + ["insert/remove .", + class_name, " before #", insert_before.id, ")"].join(""), + ": "].join(" "); + + let div = document.createElement("div"); + div.classList.add(class_name); + + parent.insertBefore(div, insert_before); + test(function() { + assert_equals(subject.matches(selector), insertion_matches_result); + }, message_prefix + "(insertion) check matches (" + + insertion_matches_result + ")"); + test(function() { + assert_equals(getComputedStyle(subject).color, insertion_subject_color); + }, message_prefix + "(insertion) check #" + subject_id + " color"); + + div.remove(); + test(function() { + assert_equals(subject.matches(selector), removal_matches_result); + }, message_prefix + "(removal) check matches (" + + removal_matches_result + ")"); + test(function() { + assert_equals(getComputedStyle(subject).color, removal_subject_color); + }, message_prefix + "(removal) check #" + subject_id + " color"); } assert_equals(getComputedStyle(has_scope).color, grey); -let selector = ".red:has(#descendant:is(.a .b))"; -changeAndTest("add", "red", "has_scope", selector, false, grey); -changeAndTest("add", "a", "parent", selector, true, red); -changeAndTest("remove", "a", "parent", selector, false, grey); -changeAndTest("add", "a", "has_scope", selector, true, red); -changeAndTest("remove", "a", "has_scope", selector, false, grey); -changeAndTest("add", "a", "child", selector, true, red); -changeAndTest("remove", "a", "child", selector, false, grey); -changeAndTest("remove", "red", "has_scope", selector, false, grey); +let selector = ".red:has(#descendant:is(.a_has_scope .b))"; +testClassChange(addClass, "red", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "a_has_scope", "parent", selector, true, "has_scope", red); +testClassChange(removeClass, "a_has_scope", "parent", selector, false, "has_scope", grey); +testClassChange(addClass, "a_has_scope", "has_scope", selector, true, "has_scope", red); +testClassChange(removeClass, "a_has_scope", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "a_has_scope", "child", selector, true, "has_scope", red); +testClassChange(removeClass, "a_has_scope", "child", selector, false, "has_scope", grey); +testClassChange(removeClass, "red", "has_scope", selector, false, "has_scope", grey); -selector = ".green:has(#descendant:is(.c ~ .d .e))"; -changeAndTest("add", "green", "has_scope", selector, false, grey); -changeAndTest("add", "c", "parent_previous", selector, true, green); -changeAndTest("remove", "c", "parent_previous", selector, false, grey); -changeAndTest("add", "c", "previous", selector, true, green); -changeAndTest("remove", "c", "previous", selector, false, grey); -changeAndTest("add", "c", "child_previous", selector, true, green); -changeAndTest("remove", "c", "child_previous", selector, false, grey); -changeAndTest("remove", "green", "has_scope", selector, false, grey); +selector = ".orangered:has(#descendant:is(.a_descendant .b)) #descendant"; +testClassChange(addClass, "orangered", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "a_descendant", "parent", selector, true, "descendant", orangered); +testClassChange(removeClass, "a_descendant", "parent", selector, false, "descendant", grey); +testClassChange(addClass, "a_descendant", "has_scope", selector, true, "descendant", orangered); +testClassChange(removeClass, "a_descendant", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "a_descendant", "child", selector, true, "descendant", orangered); +testClassChange(removeClass, "a_descendant", "child", selector, false, "descendant", grey); +testClassChange(removeClass, "orangered", "has_scope", selector, false, "descendant", grey); -selector = ".blue:has(~ #indirect_next:is(.f ~ .g))"; -changeAndTest("add", "blue", "has_scope", selector, false, grey); -changeAndTest("add", "f", "previous", selector, true, blue); -changeAndTest("remove", "f", "previous", selector, false, grey); -changeAndTest("add", "f", "has_scope", selector, true, blue); -changeAndTest("remove", "f", "has_scope", selector, false, grey); -changeAndTest("add", "f", "direct_next", selector, true, blue); -changeAndTest("remove", "f", "direct_next", selector, false, grey); -changeAndTest("remove", "blue", "has_scope", selector, false, grey); +selector = ".darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next"; +testClassChange(addClass, "darkred", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "a_indirect_next", "parent", selector, true, "indirect_next", darkred); +testClassChange(removeClass, "a_indirect_next", "parent", selector, false, "indirect_next", grey); +testClassChange(addClass, "a_indirect_next", "has_scope", selector, true, "indirect_next", darkred); +testClassChange(removeClass, "a_indirect_next", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "a_indirect_next", "child", selector, true, "indirect_next", darkred); +testClassChange(removeClass, "a_indirect_next", "child", selector, false, "indirect_next", grey); +testClassChange(removeClass, "darkred", "has_scope", selector, false, "indirect_next", grey); -selector = ".yellow:has(~ #indirect_next:is(.h .i))" -changeAndTest("add", "yellow", "has_scope", selector, false, grey); -changeAndTest("add", "h", "parent", selector, true, yellow); -changeAndTest("remove", "h", "parent", selector, false, grey); -changeAndTest("remove", "yellow", "has_scope", selector, false, grey); +selector = ".pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "pink", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "a_indirect_next_child", "parent", selector, true, "indirect_next_child", pink); +testClassChange(removeClass, "a_indirect_next_child", "parent", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "a_indirect_next_child", "has_scope", selector, true, "indirect_next_child", pink); +testClassChange(removeClass, "a_indirect_next_child", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "a_indirect_next_child", "child", selector, true, "indirect_next_child", pink); +testClassChange(removeClass, "a_indirect_next_child", "child", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "pink", "has_scope", selector, false, "indirect_next_child", grey); -selector = ".purple:has(~ #indirect_next:is(.j ~ .k .l))" -changeAndTest("add", "purple", "has_scope", selector, false, grey); -changeAndTest("add", "j", "parent_previous", selector, true, purple); -changeAndTest("remove", "j", "parent_previous", selector, false, grey); -changeAndTest("remove", "purple", "has_scope", selector, false, grey); +selector = ".green:has(#descendant:is(.p + .c_has_scope ~ .d .e))"; +testClassChange(addClass, "green", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "c_has_scope", "parent_previous", selector, true, "has_scope", green); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "has_scope", false, grey, true, green); +testClassChange(removeClass, "c_has_scope", "parent_previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("c_has_scope", "parent_previous", selector, "has_scope", true, green, false, grey); +testClassChange(addClass, "c_has_scope", "previous", selector, true, "has_scope", green); +testSiblingInsertionRemoval("invalid", "previous", selector, "has_scope", false, grey, true, green); +testClassChange(removeClass, "c_has_scope", "previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("c_has_scope", "previous", selector, "has_scope", true, green, false, grey); +testClassChange(addClass, "c_has_scope", "child_previous", selector, true, "has_scope", green); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "has_scope", false, grey, true, green); +testClassChange(removeClass, "c_has_scope", "child_previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("c_has_scope", "child_previous", selector, "has_scope", true, green, false, grey); +testClassChange(removeClass, "green", "has_scope", selector, false, "has_scope", grey); + +selector = ".lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant"; +testClassChange(addClass, "lightgreen", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "c_descendant", "parent_previous", selector, true, "descendant", lightgreen); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "descendant", false, grey, true, lightgreen); +testClassChange(removeClass, "c_descendant", "parent_previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("c_descendant", "parent_previous", selector, "descendant", true, lightgreen, false, grey); +testClassChange(addClass, "c_descendant", "previous", selector, true, "descendant", lightgreen); +testSiblingInsertionRemoval("invalid", "previous", selector, "descendant", false, grey, true, lightgreen); +testClassChange(removeClass, "c_descendant", "previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("c_descendant", "previous", selector, "descendant", true, lightgreen, false, grey); +testClassChange(addClass, "c_descendant", "child_previous", selector, true, "descendant", lightgreen); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "descendant", false, grey, true, lightgreen); +testClassChange(removeClass, "c_descendant", "child_previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("c_descendant", "child_previous", selector, "descendant", true, lightgreen, false, grey); +testClassChange(removeClass, "lightgreen", "has_scope", selector, false, "descendant", grey); + +selector = ".darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next"; +testClassChange(addClass, "darkgreen", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "c_indirect_next", "parent_previous", selector, true, "indirect_next", darkgreen); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next", false, grey, true, darkgreen); +testClassChange(removeClass, "c_indirect_next", "parent_previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("c_indirect_next", "parent_previous", selector, "indirect_next", true, darkgreen, false, grey); +testClassChange(addClass, "c_indirect_next", "previous", selector, true, "indirect_next", darkgreen); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next", false, grey, true, darkgreen); +testClassChange(removeClass, "c_indirect_next", "previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("c_indirect_next", "previous", selector, "indirect_next", true, darkgreen, false, grey); +testClassChange(addClass, "c_indirect_next", "child_previous", selector, true, "indirect_next", darkgreen); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "indirect_next", false, grey, true, darkgreen); +testClassChange(removeClass, "c_indirect_next", "child_previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("c_indirect_next", "child_previous", selector, "indirect_next", true, darkgreen, false, grey); +testClassChange(removeClass, "darkgreen", "has_scope", selector, false, "indirect_next", grey); + +selector = ".yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "yellowgreen", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "c_indirect_next_child", "parent_previous", selector, true, "indirect_next_child", yellowgreen); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next_child", false, grey, true, yellowgreen); +testClassChange(removeClass, "c_indirect_next_child", "parent_previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("c_indirect_next_child", "parent_previous", selector, "indirect_next_child", true, yellowgreen, false, grey); +testClassChange(addClass, "c_indirect_next_child", "previous", selector, true, "indirect_next_child", yellowgreen); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next_child", false, grey, true, yellowgreen); +testClassChange(removeClass, "c_indirect_next_child", "previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("c_indirect_next_child", "previous", selector, "indirect_next_child", true, yellowgreen, false, grey); +testClassChange(addClass, "c_indirect_next_child", "child_previous", selector, true, "indirect_next_child", yellowgreen); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "indirect_next_child", false, grey, true, yellowgreen); +testClassChange(removeClass, "c_indirect_next_child", "child_previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("c_indirect_next_child", "child_previous", selector, "indirect_next_child", true, yellowgreen, false, grey); +testClassChange(removeClass, "yellowgreen", "has_scope", selector, false, "indirect_next_child", grey); + +selector = ".blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g))"; +testClassChange(addClass, "blue", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "f_has_scope", "previous", selector, true, "has_scope", blue); +testSiblingInsertionRemoval("invalid", "previous", selector, "has_scope", false, grey, true, blue); +testClassChange(removeClass, "f_has_scope", "previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("f_has_scope", "previous", selector, "has_scope", true, blue, false, grey); +testClassChange(addClass, "f_has_scope", "has_scope", selector, true, "has_scope", blue); +testClassChange(removeClass, "f_has_scope", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "f_has_scope", "direct_next", selector, true, "has_scope", blue); +testSiblingInsertionRemoval("invalid", "direct_next", selector, "has_scope", false, grey, true, blue); +testClassChange(removeClass, "f_has_scope", "direct_next", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("f_has_scope", "direct_next", selector, "has_scope", true, blue, false, grey); +testClassChange(removeClass, "blue", "has_scope", selector, false, "has_scope", grey); + +selector = ".skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant"; +testClassChange(addClass, "skyblue", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "f_descendant", "previous", selector, true, "descendant", skyblue); +testSiblingInsertionRemoval("invalid", "previous", selector, "descendant", false, grey, true, skyblue); +testClassChange(removeClass, "f_descendant", "previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("f_descendant", "previous", selector, "descendant", true, skyblue, false, grey); +testClassChange(addClass, "f_descendant", "has_scope", selector, true, "descendant", skyblue); +testClassChange(removeClass, "f_descendant", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "f_descendant", "direct_next", selector, true, "descendant", skyblue); +testSiblingInsertionRemoval("invalid", "direct_next", selector, "descendant", false, grey, true, skyblue); +testClassChange(removeClass, "f_descendant", "direct_next", selector, false, "descendant", grey); +testSiblingInsertionRemoval("f_descendant", "direct_next", selector, "descendant", true, skyblue, false, grey); +testClassChange(removeClass, "skyblue", "has_scope", selector, false, "descendant", grey); + +selector = ".lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next"; +testClassChange(addClass, "lightblue", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "f_indirect_next", "previous", selector, true, "indirect_next", lightblue); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next", false, grey, true, lightblue); +testClassChange(removeClass, "f_indirect_next", "previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("f_indirect_next", "previous", selector, "indirect_next", true, lightblue, false, grey); +testClassChange(addClass, "f_indirect_next", "has_scope", selector, true, "indirect_next", lightblue); +testClassChange(removeClass, "f_indirect_next", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "f_indirect_next", "direct_next", selector, true, "indirect_next", lightblue); +testSiblingInsertionRemoval("invalid", "direct_next", selector, "indirect_next", false, grey, true, lightblue); +testClassChange(removeClass, "f_indirect_next", "direct_next", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("f_indirect_next", "direct_next", selector, "indirect_next", true, lightblue, false, grey); +testClassChange(removeClass, "lightblue", "has_scope", selector, false, "indirect_next", grey); + +selector = ".darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "darkblue", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "f_indirect_next_child", "previous", selector, true, "indirect_next_child", darkblue); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next_child", false, grey, true, darkblue); +testClassChange(removeClass, "f_indirect_next_child", "previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("f_indirect_next_child", "previous", selector, "indirect_next_child", true, darkblue, false, grey); +testClassChange(addClass, "f_indirect_next_child", "has_scope", selector, true, "indirect_next_child", darkblue); +testClassChange(removeClass, "f_indirect_next_child", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "f_indirect_next_child", "direct_next", selector, true, "indirect_next_child", darkblue); +testSiblingInsertionRemoval("invalid", "direct_next", selector, "indirect_next_child", false, grey, true, darkblue); +testClassChange(removeClass, "f_indirect_next_child", "direct_next", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("f_indirect_next_child", "direct_next", selector, "indirect_next_child", true, darkblue, false, grey); +testClassChange(removeClass, "darkblue", "has_scope", selector, false, "indirect_next_child", grey); + +selector = ".yellow:has(~ #indirect_next:is(.h_has_scope .i))" +testClassChange(addClass, "yellow", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "h_has_scope", "parent", selector, true, "has_scope", yellow); +testClassChange(removeClass, "h_has_scope", "parent", selector, false, "has_scope", grey); +testClassChange(removeClass, "yellow", "has_scope", selector, false, "has_scope", grey); + +selector = ".ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant"; +testClassChange(addClass, "ivory", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "h_descendant", "parent", selector, true, "descendant", ivory); +testClassChange(removeClass, "h_descendant", "parent", selector, false, "descendant", grey); +testClassChange(removeClass, "ivory", "has_scope", selector, false, "descendant", grey); + +selector = ".greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next"; +testClassChange(addClass, "greenyellow", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "h_indirect_next", "parent", selector, true, "indirect_next", greenyellow); +testClassChange(removeClass, "h_indirect_next", "parent", selector, false, "indirect_next", grey); +testClassChange(removeClass, "greenyellow", "has_scope", selector, false, "indirect_next", grey); + +selector = ".khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "khaki", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "h_indirect_next_child", "parent", selector, true, "indirect_next_child", khaki); +testClassChange(removeClass, "h_indirect_next_child", "parent", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "khaki", "has_scope", selector, false, "indirect_next_child", grey); + +selector = ".purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l))" +testClassChange(addClass, "purple", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "j_has_scope", "parent_previous", selector, true, "has_scope", purple); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "has_scope", false, grey, true, purple); +testClassChange(removeClass, "j_has_scope", "parent_previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("j_has_scope", "parent_previous", selector, "has_scope", true, purple, false, grey); +testClassChange(removeClass, "purple", "has_scope", selector, false, "has_scope", grey); + +selector = ".violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant"; +testClassChange(addClass, "violet", "has_scope", selector, false, "descendant", grey); +testClassChange(addClass, "j_descendant", "parent_previous", selector, true, "descendant", violet); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "descendant", false, grey, true, violet); +testClassChange(removeClass, "j_descendant", "parent_previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("j_descendant", "parent_previous", selector, "descendant", true, violet, false, grey); +testClassChange(removeClass, "violet", "has_scope", selector, false, "descendant", grey); + +selector = ".orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next"; +testClassChange(addClass, "orchid", "has_scope", selector, false, "indirect_next", grey); +testClassChange(addClass, "j_indirect_next", "parent_previous", selector, true, "indirect_next", orchid); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next", false, grey, true, orchid); +testClassChange(removeClass, "j_indirect_next", "parent_previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("j_indirect_next", "parent_previous", selector, "indirect_next", true, orchid, false, grey); +testClassChange(removeClass, "orchid", "has_scope", selector, false, "indirect_next", grey); + +selector = ".plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "plum", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(addClass, "j_indirect_next_child", "parent_previous", selector, true, "indirect_next_child", plum); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next_child", false, grey, true, plum); +testClassChange(removeClass, "j_indirect_next_child", "parent_previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("j_indirect_next_child", "parent_previous", selector, "indirect_next_child", true, plum, false, grey); +testClassChange(removeClass, "plum", "has_scope", selector, false, "indirect_next_child", grey); selector = ".orange:has(#descendant:is(:is(.m, .n) .o))"; -changeAndTest("add", "orange", "has_scope", selector, false, grey); -changeAndTest("add", "m", "parent", selector, true, orange); -changeAndTest("remove", "m", "parent", selector, false, grey); -changeAndTest("add", "n", "parent", selector, true, orange); -changeAndTest("remove", "n", "parent", selector, false, grey); -changeAndTest("add", "m", "has_scope", selector, true, orange); -changeAndTest("remove", "m", "has_scope", selector, false, grey); -changeAndTest("add", "n", "has_scope", selector, true, orange); -changeAndTest("remove", "n", "has_scope", selector, false, grey); -changeAndTest("add", "m", "child", selector, true, orange); -changeAndTest("remove", "m", "child", selector, false, grey); -changeAndTest("add", "n", "child", selector, true, orange); -changeAndTest("remove", "n", "child", selector, false, grey); -changeAndTest("remove", "orange", "has_scope", selector, false, grey); +testClassChange(addClass, "orange", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "m", "parent", selector, true, "has_scope", orange); +testClassChange(removeClass, "m", "parent", selector, false, "has_scope", grey); +testClassChange(addClass, "n", "parent", selector, true, "has_scope", orange); +testClassChange(removeClass, "n", "parent", selector, false, "has_scope", grey); +testClassChange(addClass, "m", "has_scope", selector, true, "has_scope", orange); +testClassChange(removeClass, "m", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "n", "has_scope", selector, true, "has_scope", orange); +testClassChange(removeClass, "n", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "m", "child", selector, true, "has_scope", orange); +testClassChange(removeClass, "m", "child", selector, false, "has_scope", grey); +testClassChange(addClass, "n", "child", selector, true, "has_scope", orange); +testClassChange(removeClass, "n", "child", selector, false, "has_scope", grey); +testClassChange(removeClass, "orange", "has_scope", selector, false, "has_scope", grey); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has.html index b99b309..d24abf6 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has.html +++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has.html
@@ -7,115 +7,369 @@ <script src="/resources/testharnessreport.js"></script> <style> div { color: grey } -.red:has(#descendant:not(.a .b)) { color: red } -.green:has(#descendant:not(.c ~ .d .e)) { color: green } -.blue:has(~ #indirect_next:not(.f ~ .g)) { color: blue } -.yellow:has(~ #indirect_next:not(.h .i)) { color: yellow } -.purple:has(~ #indirect_next:not(.j ~ .k .l)) { color: purple } +.red:has(#descendant:not(.a_has_scope .b)) { color: red } +.orangered:has(#descendant:not(.a_descendant .b)) #descendant { color: orangered } +.darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next { color: darkred } +.pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child { color: pink } +.green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) { color: green } +.lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant { color: lightgreen } +.darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next { color: darkgreen } +.yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child { color: yellowgreen } +.blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) { color: blue } +.skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant { color: skyblue } +.lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next { color: lightblue } +.darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child { color: darkblue } +.yellow:has(~ #indirect_next:not(.h_has_scope .i)) { color: yellow } +.ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant { color: ivory } +.greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next { color: greenyellow } +.khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child { color: khaki } +.purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) { color: purple } +.violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant { color: violet } +.orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next { color: orchid } +.plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child { color: plum } .orange:has(#descendant:not(.m:not(.n) .o)) { color: orange } </style> <div> + <div class="p"></div> <div id="parent_previous"></div> <div id="parent" class="d k"> + <div class="p"></div> <div id="previous"></div> + <div class="p"></div> <div id="has_scope" class="d"> + <div class="p"></div> <div id="child_previous"></div> <div id="child" class="d"> <div id="descendant" class="b e o"></div> </div> </div> + <div class="p"></div> <div id="direct_next"></div> - <div id="indirect_next" class="g i l"></div> + <div id="indirect_next" class="g i l"> + <div id="indirect_next_child"></div> + </div> </div> </div> <script> const grey = "rgb(128, 128, 128)"; const red = "rgb(255, 0, 0)"; +const orangered = "rgb(255, 69, 0)"; +const darkred = "rgb(139, 0, 0)"; +const pink = "rgb(255, 192, 203)"; const green = "rgb(0, 128, 0)"; +const lightgreen = "rgb(144, 238, 144)"; +const darkgreen = "rgb(0, 100, 0)"; +const yellowgreen = "rgb(154, 205, 50)"; const blue = "rgb(0, 0, 255)"; +const skyblue = "rgb(135, 206, 235)"; +const lightblue = "rgb(173, 216, 230)"; +const darkblue = "rgb(0, 0, 139)"; const yellow = "rgb(255, 255, 0)"; +const ivory = "rgb(255, 255, 240)"; +const greenyellow = "rgb(173, 255, 47)"; +const khaki = "rgb(240, 230, 140)"; const purple = "rgb(128, 0, 128)"; +const violet = "rgb(238, 130, 238)"; +const orchid = "rgb(218, 112, 214)"; +const plum = "rgb(221, 160, 221)"; const orange = "rgb(255, 165, 0)"; -function changeAndTest(operation, class_name, element_id, - selector, matches_result, scope_color) { +function addClass(element, class_name) { + element.classList.add(class_name); +} + +function removeClass(element, class_name) { + element.classList.remove(class_name); +} + +function testClassChange(operation, class_name, element_id, + selector, matches_result, + subject_id, subject_color) { let element = document.getElementById(element_id); assert_equals(element ? element.id : "", element_id); + let subject = document.getElementById(subject_id); + assert_equals(subject ? subject.id : "", subject_id); let message_prefix = [ "[", selector, "]", - ["#", element.id, ".classList.", operation, "('", class_name, "')"].join(""), + ["#", element.id, ".classList.", + (operation == addClass ? "add" : "remove"), + "('", class_name, "')"].join(""), ": "].join(" "); - if (operation == "add") { - element.classList.add(class_name); - } else { - assert_equals(operation, "remove"); - element.classList.remove(class_name); - } + operation(element, class_name); test(function() { - assert_equals(has_scope.matches(selector), matches_result); + assert_equals(subject.matches(selector), matches_result); }, message_prefix + "check matches (" + matches_result + ")"); test(function() { - assert_equals(getComputedStyle(has_scope).color, scope_color); - }, message_prefix + "check #has_scope color"); + assert_equals(getComputedStyle(subject).color, subject_color); + }, message_prefix + "check #" + subject_id + " color"); +} + +function testSiblingInsertionRemoval(class_name, insert_before_id, selector, + subject_id, + insertion_matches_result, + insertion_subject_color, + removal_matches_result, + removal_subject_color) { + let insert_before = document.getElementById(insert_before_id); + assert_equals(insert_before ? insert_before.id : "", insert_before_id); + let parent = insert_before.parentElement; + let subject = document.getElementById(subject_id); + assert_equals(subject ? subject.id : "", subject_id); + let message_prefix = [ + "[", selector, "]", + ["insert/remove .", + class_name, " before #", insert_before.id, ")"].join(""), + ": "].join(" "); + + let div = document.createElement("div"); + div.classList.add(class_name); + + parent.insertBefore(div, insert_before); + test(function() { + assert_equals(subject.matches(selector), insertion_matches_result); + }, message_prefix + "(insertion) check matches (" + + insertion_matches_result + ")"); + test(function() { + assert_equals(getComputedStyle(subject).color, insertion_subject_color); + }, message_prefix + "(insertion) check #" + subject_id + " color"); + + div.remove(); + test(function() { + assert_equals(subject.matches(selector), removal_matches_result); + }, message_prefix + "(removal) check matches (" + + removal_matches_result + ")"); + test(function() { + assert_equals(getComputedStyle(subject).color, removal_subject_color); + }, message_prefix + "(removal) check #" + subject_id + " color"); } assert_equals(getComputedStyle(has_scope).color, grey); -let selector = ".red:has(#descendant:not(.a .b))"; -changeAndTest("add", "red", "has_scope", selector, true, red); -changeAndTest("add", "a", "parent", selector, false, grey); -changeAndTest("remove", "a", "parent", selector, true, red); -changeAndTest("add", "a", "has_scope", selector, false, grey); -changeAndTest("remove", "a", "has_scope", selector, true, red); -changeAndTest("add", "a", "child", selector, false, grey); -changeAndTest("remove", "a", "child", selector, true, red); -changeAndTest("remove", "red", "has_scope", selector, false, grey); +let selector = ".red:has(#descendant:not(.a_has_scope .b))"; +testClassChange(addClass, "red", "has_scope", selector, true, "has_scope", red); +testClassChange(addClass, "a_has_scope", "parent", selector, false, "has_scope", grey); +testClassChange(removeClass, "a_has_scope", "parent", selector, true, "has_scope", red); +testClassChange(addClass, "a_has_scope", "has_scope", selector, false, "has_scope", grey); +testClassChange(removeClass, "a_has_scope", "has_scope", selector, true, "has_scope", red); +testClassChange(addClass, "a_has_scope", "child", selector, false, "has_scope", grey); +testClassChange(removeClass, "a_has_scope", "child", selector, true, "has_scope", red); +testClassChange(removeClass, "red", "has_scope", selector, false, "has_scope", grey); -selector = ".green:has(#descendant:not(.c ~ .d .e))"; -changeAndTest("add", "green", "has_scope", selector, true, green); -changeAndTest("add", "c", "parent_previous", selector, false, grey); -changeAndTest("remove", "c", "parent_previous", selector, true, green); -changeAndTest("add", "c", "previous", selector, false, grey); -changeAndTest("remove", "c", "previous", selector, true, green); -changeAndTest("add", "c", "child_previous", selector, false, grey); -changeAndTest("remove", "c", "child_previous", selector, true, green); -changeAndTest("remove", "green", "has_scope", selector, false, grey); +selector = ".orangered:has(#descendant:not(.a_descendant .b)) #descendant"; +testClassChange(addClass, "orangered", "has_scope", selector, true, "descendant", orangered); +testClassChange(addClass, "a_descendant", "parent", selector, false, "descendant", grey); +testClassChange(removeClass, "a_descendant", "parent", selector, true, "descendant", orangered); +testClassChange(addClass, "a_descendant", "has_scope", selector, false, "descendant", grey); +testClassChange(removeClass, "a_descendant", "has_scope", selector, true, "descendant", orangered); +testClassChange(addClass, "a_descendant", "child", selector, false, "descendant", grey); +testClassChange(removeClass, "a_descendant", "child", selector, true, "descendant", orangered); +testClassChange(removeClass, "orangered", "has_scope", selector, false, "descendant", grey); -selector = ".blue:has(~ #indirect_next:not(.f ~ .g))"; -changeAndTest("add", "blue", "has_scope", selector, true, blue); -changeAndTest("add", "f", "previous", selector, false, grey); -changeAndTest("remove", "f", "previous", selector, true, blue); -changeAndTest("add", "f", "has_scope", selector, false, grey); -changeAndTest("remove", "f", "has_scope", selector, true, blue); -changeAndTest("add", "f", "direct_next", selector, false, grey); -changeAndTest("remove", "f", "direct_next", selector, true, blue); -changeAndTest("remove", "blue", "has_scope", selector, false, grey); +selector = ".darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next"; +testClassChange(addClass, "darkred", "has_scope", selector, true, "indirect_next", darkred); +testClassChange(addClass, "a_indirect_next", "parent", selector, false, "indirect_next", grey); +testClassChange(removeClass, "a_indirect_next", "parent", selector, true, "indirect_next", darkred); +testClassChange(addClass, "a_indirect_next", "has_scope", selector, false, "indirect_next", grey); +testClassChange(removeClass, "a_indirect_next", "has_scope", selector, true, "indirect_next", darkred); +testClassChange(addClass, "a_indirect_next", "child", selector, false, "indirect_next", grey); +testClassChange(removeClass, "a_indirect_next", "child", selector, true, "indirect_next", darkred); +testClassChange(removeClass, "darkred", "has_scope", selector, false, "indirect_next", grey); -selector = ".yellow:has(~ #indirect_next:not(.h .i))" -changeAndTest("add", "yellow", "has_scope", selector, true, yellow); -changeAndTest("add", "h", "parent", selector, false, grey); -changeAndTest("remove", "h", "parent", selector, true, yellow); -changeAndTest("remove", "yellow", "has_scope", selector, false, grey); +selector = ".pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "pink", "has_scope", selector, true, "indirect_next_child", pink); +testClassChange(addClass, "a_indirect_next_child", "parent", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "a_indirect_next_child", "parent", selector, true, "indirect_next_child", pink); +testClassChange(addClass, "a_indirect_next_child", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "a_indirect_next_child", "has_scope", selector, true, "indirect_next_child", pink); +testClassChange(addClass, "a_indirect_next_child", "child", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "a_indirect_next_child", "child", selector, true, "indirect_next_child", pink); +testClassChange(removeClass, "pink", "has_scope", selector, false, "indirect_next_child", grey); -selector = ".purple:has(~ #indirect_next:not(.j ~ .k .l))" -changeAndTest("add", "purple", "has_scope", selector, true, purple); -changeAndTest("add", "j", "parent_previous", selector, false, grey); -changeAndTest("remove", "j", "parent_previous", selector, true, purple); -changeAndTest("remove", "purple", "has_scope", selector, false, grey); +selector = ".green:has(#descendant:not(.p + .c_has_scope ~ .d .e))"; +testClassChange(addClass, "green", "has_scope", selector, true, "has_scope", green); +testClassChange(addClass, "c_has_scope", "parent_previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "has_scope", true, green, false, grey); +testClassChange(removeClass, "c_has_scope", "parent_previous", selector, true, "has_scope", green); +testSiblingInsertionRemoval("c_has_scope", "parent_previous", selector, "has_scope", false, grey, true, green); +testClassChange(addClass, "c_has_scope", "previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("invalid", "previous", selector, "has_scope", true, green, false, grey); +testClassChange(removeClass, "c_has_scope", "previous", selector, true, "has_scope", green); +testSiblingInsertionRemoval("c_has_scope", "previous", selector, "has_scope", false, grey, true, green); +testClassChange(addClass, "c_has_scope", "child_previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "has_scope", true, green, false, grey); +testClassChange(removeClass, "c_has_scope", "child_previous", selector, true, "has_scope", green); +testSiblingInsertionRemoval("c_has_scope", "child_previous", selector, "has_scope", false, grey, true, green); +testClassChange(removeClass, "green", "has_scope", selector, false, "has_scope", grey); + +selector = ".lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant"; +testClassChange(addClass, "lightgreen", "has_scope", selector, true, "descendant", lightgreen); +testClassChange(addClass, "c_descendant", "parent_previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "descendant", true, lightgreen, false, grey); +testClassChange(removeClass, "c_descendant", "parent_previous", selector, true, "descendant", lightgreen); +testSiblingInsertionRemoval("c_descendant", "parent_previous", selector, "descendant", false, grey, true, lightgreen); +testClassChange(addClass, "c_descendant", "previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("invalid", "previous", selector, "descendant", true, lightgreen, false, grey); +testClassChange(removeClass, "c_descendant", "previous", selector, true, "descendant", lightgreen); +testSiblingInsertionRemoval("c_descendant", "previous", selector, "descendant", false, grey, true, lightgreen); +testClassChange(addClass, "c_descendant", "child_previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "descendant", true, lightgreen, false, grey); +testClassChange(removeClass, "c_descendant", "child_previous", selector, true, "descendant", lightgreen); +testSiblingInsertionRemoval("c_descendant", "child_previous", selector, "descendant", false, grey, true, lightgreen); +testClassChange(removeClass, "lightgreen", "has_scope", selector, false, "descendant", grey); + +selector = ".darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next"; +testClassChange(addClass, "darkgreen", "has_scope", selector, true, "indirect_next", darkgreen); +testClassChange(addClass, "c_indirect_next", "parent_previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next", true, darkgreen, false, grey); +testClassChange(removeClass, "c_indirect_next", "parent_previous", selector, true, "indirect_next", darkgreen); +testSiblingInsertionRemoval("c_indirect_next", "parent_previous", selector, "indirect_next", false, grey, true, darkgreen); +testClassChange(addClass, "c_indirect_next", "previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next", true, darkgreen, false, grey); +testClassChange(removeClass, "c_indirect_next", "previous", selector, true, "indirect_next", darkgreen); +testSiblingInsertionRemoval("c_indirect_next", "previous", selector, "indirect_next", false, grey, true, darkgreen); +testClassChange(addClass, "c_indirect_next", "child_previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "indirect_next", true, darkgreen, false, grey); +testClassChange(removeClass, "c_indirect_next", "child_previous", selector, true, "indirect_next", darkgreen); +testSiblingInsertionRemoval("c_indirect_next", "child_previous", selector, "indirect_next", false, grey, true, darkgreen); +testClassChange(removeClass, "darkgreen", "has_scope", selector, false, "indirect_next", grey); + +selector = ".yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "yellowgreen", "has_scope", selector, true, "indirect_next_child", yellowgreen); +testClassChange(addClass, "c_indirect_next_child", "parent_previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next_child", true, yellowgreen, false, grey); +testClassChange(removeClass, "c_indirect_next_child", "parent_previous", selector, true, "indirect_next_child", yellowgreen); +testSiblingInsertionRemoval("c_indirect_next_child", "parent_previous", selector, "indirect_next_child", false, grey, true, yellowgreen); +testClassChange(addClass, "c_indirect_next_child", "previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next_child", true, yellowgreen, false, grey); +testClassChange(removeClass, "c_indirect_next_child", "previous", selector, true, "indirect_next_child", yellowgreen); +testSiblingInsertionRemoval("c_indirect_next_child", "previous", selector, "indirect_next_child", false, grey, true, yellowgreen); +testClassChange(addClass, "c_indirect_next_child", "child_previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("invalid", "child_previous", selector, "indirect_next_child", true, yellowgreen, false, grey); +testClassChange(removeClass, "c_indirect_next_child", "child_previous", selector, true, "indirect_next_child", yellowgreen); +testSiblingInsertionRemoval("c_indirect_next_child", "child_previous", selector, "indirect_next_child", false, grey, true, yellowgreen); +testClassChange(removeClass, "yellowgreen", "has_scope", selector, false, "indirect_next_child", grey); + +selector = ".blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g))"; +testClassChange(addClass, "blue", "has_scope", selector, true, "has_scope", blue); +testClassChange(addClass, "f_has_scope", "previous", selector, false, "has_scope", grey); +testClassChange(removeClass, "f_has_scope", "previous", selector, true, "has_scope", blue); +testSiblingInsertionRemoval("f_has_scope", "previous", selector, "has_scope", false, grey, true, blue); +testClassChange(addClass, "f_has_scope", "has_scope", selector, false, "has_scope", grey); +testClassChange(removeClass, "f_has_scope", "has_scope", selector, true, "has_scope", blue); +testClassChange(addClass, "f_has_scope", "direct_next", selector, false, "has_scope", grey); +testClassChange(removeClass, "f_has_scope", "direct_next", selector, true, "has_scope", blue); +testSiblingInsertionRemoval("f_has_scope", "direct_next", selector, "has_scope", false, grey, true, blue); +testClassChange(removeClass, "blue", "has_scope", selector, false, "has_scope", grey); + +selector = ".skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant"; +testClassChange(addClass, "skyblue", "has_scope", selector, true, "descendant", skyblue); +testClassChange(addClass, "f_descendant", "previous", selector, false, "descendant", grey); +testClassChange(removeClass, "f_descendant", "previous", selector, true, "descendant", skyblue); +testSiblingInsertionRemoval("f_descendant", "previous", selector, "descendant", false, grey, true, skyblue); +testClassChange(addClass, "f_descendant", "has_scope", selector, false, "descendant", grey); +testClassChange(removeClass, "f_descendant", "has_scope", selector, true, "descendant", skyblue); +testClassChange(addClass, "f_descendant", "direct_next", selector, false, "descendant", grey); +testClassChange(removeClass, "f_descendant", "direct_next", selector, true, "descendant", skyblue); +testSiblingInsertionRemoval("f_descendant", "direct_next", selector, "descendant", false, grey, true, skyblue); +testClassChange(removeClass, "skyblue", "has_scope", selector, false, "descendant", grey); + +selector = ".lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next"; +testClassChange(addClass, "lightblue", "has_scope", selector, true, "indirect_next", lightblue); +testClassChange(addClass, "f_indirect_next", "previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next", true, lightblue, false, grey); +testClassChange(removeClass, "f_indirect_next", "previous", selector, true, "indirect_next", lightblue); +testSiblingInsertionRemoval("f_indirect_next", "previous", selector, "indirect_next", false, grey, true, lightblue); +testClassChange(addClass, "f_indirect_next", "has_scope", selector, false, "indirect_next", grey); +testClassChange(removeClass, "f_indirect_next", "has_scope", selector, true, "indirect_next", lightblue); +testClassChange(addClass, "f_indirect_next", "direct_next", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("invalid", "direct_next", selector, "indirect_next", true, lightblue, false, grey); +testClassChange(removeClass, "f_indirect_next", "direct_next", selector, true, "indirect_next", lightblue); +testSiblingInsertionRemoval("f_indirect_next", "direct_next", selector, "indirect_next", false, grey, true, lightblue); +testClassChange(removeClass, "lightblue", "has_scope", selector, false, "indirect_next", grey); + +selector = ".darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "darkblue", "has_scope", selector, true, "indirect_next_child", darkblue); +testClassChange(addClass, "f_indirect_next_child", "previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("invalid", "previous", selector, "indirect_next_child", true, darkblue, false, grey); +testClassChange(removeClass, "f_indirect_next_child", "previous", selector, true, "indirect_next_child", darkblue); +testSiblingInsertionRemoval("f_indirect_next_child", "previous", selector, "indirect_next_child", false, grey, true, darkblue); +testClassChange(addClass, "f_indirect_next_child", "has_scope", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "f_indirect_next_child", "has_scope", selector, true, "indirect_next_child", darkblue); +testClassChange(addClass, "f_indirect_next_child", "direct_next", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("invalid", "direct_next", selector, "indirect_next_child", true, darkblue, false, grey); +testClassChange(removeClass, "f_indirect_next_child", "direct_next", selector, true, "indirect_next_child", darkblue); +testSiblingInsertionRemoval("f_indirect_next_child", "direct_next", selector, "indirect_next_child", false, grey, true, darkblue); +testClassChange(removeClass, "darkblue", "has_scope", selector, false, "indirect_next_child", grey); + +selector = ".yellow:has(~ #indirect_next:not(.h_has_scope .i))" +testClassChange(addClass, "yellow", "has_scope", selector, true, "has_scope", yellow); +testClassChange(addClass, "h_has_scope", "parent", selector, false, "has_scope", grey); +testClassChange(removeClass, "h_has_scope", "parent", selector, true, "has_scope", yellow); +testClassChange(removeClass, "yellow", "has_scope", selector, false, "has_scope", grey); + +selector = ".ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant"; +testClassChange(addClass, "ivory", "has_scope", selector, true, "descendant", ivory); +testClassChange(addClass, "h_descendant", "parent", selector, false, "descendant", grey); +testClassChange(removeClass, "h_descendant", "parent", selector, true, "descendant", ivory); +testClassChange(removeClass, "ivory", "has_scope", selector, false, "descendant", grey); + +selector = ".greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next"; +testClassChange(addClass, "greenyellow", "has_scope", selector, true, "indirect_next", greenyellow); +testClassChange(addClass, "h_indirect_next", "parent", selector, false, "indirect_next", grey); +testClassChange(removeClass, "h_indirect_next", "parent", selector, true, "indirect_next", greenyellow); +testClassChange(removeClass, "greenyellow", "has_scope", selector, false, "indirect_next", grey); + +selector = ".khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "khaki", "has_scope", selector, true, "indirect_next_child", khaki); +testClassChange(addClass, "h_indirect_next_child", "parent", selector, false, "indirect_next_child", grey); +testClassChange(removeClass, "h_indirect_next_child", "parent", selector, true, "indirect_next_child", khaki); +testClassChange(removeClass, "khaki", "has_scope", selector, false, "indirect_next_child", grey); + +selector = ".purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l))" +testClassChange(addClass, "purple", "has_scope", selector, true, "has_scope", purple); +testClassChange(addClass, "j_has_scope", "parent_previous", selector, false, "has_scope", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "has_scope", true, purple, false, grey); +testClassChange(removeClass, "j_has_scope", "parent_previous", selector, true, "has_scope", purple); +testSiblingInsertionRemoval("j_has_scope", "parent_previous", selector, "has_scope", false, grey, true, purple); +testClassChange(removeClass, "purple", "has_scope", selector, false, "has_scope", grey); + +selector = ".violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant"; +testClassChange(addClass, "violet", "has_scope", selector, true, "descendant", violet); +testClassChange(addClass, "j_descendant", "parent_previous", selector, false, "descendant", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "descendant", true, violet, false, grey); +testClassChange(removeClass, "j_descendant", "parent_previous", selector, true, "descendant", violet); +testSiblingInsertionRemoval("j_descendant", "parent_previous", selector, "descendant", false, grey, true, violet); +testClassChange(removeClass, "violet", "has_scope", selector, false, "descendant", grey); + +selector = ".orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next"; +testClassChange(addClass, "orchid", "has_scope", selector, true, "indirect_next", orchid); +testClassChange(addClass, "j_indirect_next", "parent_previous", selector, false, "indirect_next", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next", true, orchid, false, grey); +testClassChange(removeClass, "j_indirect_next", "parent_previous", selector, true, "indirect_next", orchid); +testSiblingInsertionRemoval("j_indirect_next", "parent_previous", selector, "indirect_next", false, grey, true, orchid); +testClassChange(removeClass, "orchid", "has_scope", selector, false, "indirect_next", grey); + +selector = ".plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child"; +testClassChange(addClass, "plum", "has_scope", selector, true, "indirect_next_child", plum); +testClassChange(addClass, "j_indirect_next_child", "parent_previous", selector, false, "indirect_next_child", grey); +testSiblingInsertionRemoval("invalid", "parent_previous", selector, "indirect_next_child", true, plum, false, grey); +testClassChange(removeClass, "j_indirect_next_child", "parent_previous", selector, true, "indirect_next_child", plum); +testSiblingInsertionRemoval("j_indirect_next_child", "parent_previous", selector, "indirect_next_child", false, grey, true, plum); +testClassChange(removeClass, "plum", "has_scope", selector, false, "indirect_next_child", grey); selector = ".orange:has(#descendant:not(.m:not(.n) .o))"; -changeAndTest("add", "orange", "has_scope", selector, true, orange); -changeAndTest("add", "m", "parent", selector, false, grey); -changeAndTest("add", "n", "parent", selector, true, orange); -changeAndTest("remove", "n", "parent", selector, false, grey); -changeAndTest("remove", "m", "parent", selector, true, orange); -changeAndTest("add", "m", "has_scope", selector, false, grey); -changeAndTest("add", "n", "has_scope", selector, true, orange); -changeAndTest("remove", "n", "has_scope", selector, false, grey); -changeAndTest("remove", "m", "has_scope", selector, true, orange); -changeAndTest("add", "m", "child", selector, false, grey); -changeAndTest("add", "n", "child", selector, true, orange); -changeAndTest("remove", "n", "child", selector, false, grey); -changeAndTest("remove", "m", "child", selector, true, orange); -changeAndTest("remove", "orange", "has_scope", selector, false, grey); +testClassChange(addClass, "orange", "has_scope", selector, true, "has_scope", orange); +testClassChange(addClass, "m", "parent", selector, false, "has_scope", grey); +testClassChange(addClass, "n", "parent", selector, true, "has_scope", orange); +testClassChange(removeClass, "n", "parent", selector, false, "has_scope", grey); +testClassChange(removeClass, "m", "parent", selector, true, "has_scope", orange); +testClassChange(addClass, "m", "has_scope", selector, false, "has_scope", grey); +testClassChange(addClass, "n", "has_scope", selector, true, "has_scope", orange); +testClassChange(removeClass, "n", "has_scope", selector, false, "has_scope", grey); +testClassChange(removeClass, "m", "has_scope", selector, true, "has_scope", orange); +testClassChange(addClass, "m", "child", selector, false, "has_scope", grey); +testClassChange(addClass, "n", "child", selector, true, "has_scope", orange); +testClassChange(removeClass, "n", "child", selector, false, "has_scope", grey); +testClassChange(removeClass, "m", "child", selector, true, "has_scope", orange); +testClassChange(removeClass, "orange", "has_scope", selector, false, "has_scope", grey); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/parsing/parse-has.html b/third_party/blink/web_tests/external/wpt/css/selectors/parsing/parse-has.html index 219a6c9..e7d4ab6a 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/parsing/parse-has.html +++ b/third_party/blink/web_tests/external/wpt/css/selectors/parsing/parse-has.html
@@ -32,7 +32,7 @@ test_valid_selector('.a:has(.b):has(.c)'); test_valid_selector('*|*:has(*)', ':has(*)'); test_valid_selector(':has(*|*)', ':has(*)'); - test_invalid_selector('.a:has()'); + test_valid_selector('.a:has()', '.a:has()'); test_invalid_selector(':has'); test_invalid_selector('.a:has'); test_invalid_selector('.a:has b');
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-color/system-color-compute-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-color/system-color-compute-expected.txt new file mode 100644 index 0000000..d16956e --- /dev/null +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-color/system-color-compute-expected.txt
@@ -0,0 +1,30 @@ +This is a testharness.js-based test. +PASS color-scheme property affects Menu system color keyword +FAIL System color doesn't compute to itself on color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on color assert_false: expected false got true +FAIL System color doesn't compute to itself on background-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on background-color assert_false: expected false got true +FAIL System color doesn't compute to itself on box-shadow assert_not_equals: got disallowed value "rgb(18, 18, 18) 2px 2px 0px 0px" +FAIL Inherited system color keyword is observable on box-shadow assert_false: expected false got true +FAIL System color doesn't compute to itself on text-shadow assert_not_equals: got disallowed value "menu 2px 2px 0px" +FAIL Inherited system color keyword is observable on text-shadow assert_false: expected false got true +FAIL System color doesn't compute to itself on border-left-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-left-color assert_false: expected false got true +FAIL System color doesn't compute to itself on border-top-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-top-color assert_false: expected false got true +FAIL System color doesn't compute to itself on border-right-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-right-color assert_false: expected false got true +FAIL System color doesn't compute to itself on border-bottom-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-bottom-color assert_false: expected false got true +FAIL System color doesn't compute to itself on column-rule-color assert_not_equals: got disallowed value "menu" +FAIL Inherited system color keyword is observable on column-rule-color assert_false: expected false got true +FAIL System color doesn't compute to itself on outline-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on outline-color assert_false: expected false got true +FAIL System color doesn't compute to itself on caret-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on caret-color assert_false: expected false got true +FAIL System color doesn't compute to itself on fill assert_not_equals: got disallowed value "menu" +FAIL Inherited system color keyword is observable on fill assert_false: expected false got true +FAIL System color doesn't compute to itself on stroke assert_not_equals: got disallowed value "menu" +FAIL Inherited system color keyword is observable on stroke assert_false: expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/host-pseudo-class-in-has-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/host-pseudo-class-in-has-expected.txt new file mode 100644 index 0000000..5230719 --- /dev/null +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/host-pseudo-class-in-has-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Before adding 'a' to #host_parent: Check #subject1 color +PASS Before adding 'a' to #host_parent: Check #subject2 color +FAIL After adding 'a' to #host_parent: Check #subject1 color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)" +FAIL After adding 'a' to #host_parent: Check #subject2 color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(255, 0, 0)" +PASS After removing 'a' from #host_parent: Check #subject1 color +PASS After removing 'a' from #host_parent: Check #subject2 color +FAIL After adding 'a' to #host: Check #subject1 color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(255, 0, 0)" +FAIL After adding 'a' to #host: Check #subject2 color assert_equals: expected "rgb(135, 206, 235)" but got "rgb(255, 0, 0)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt index c94f96e8..c119941 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt
@@ -1,69 +1,453 @@ This is a testharness.js-based test. -Found 92 tests; 80 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.add('red') : check matches (false) -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.add('red') : check #has_scope color -PASS [ .red:has(#descendant:is(.a .b)) ] #parent.classList.add('a') : check matches (true) -FAIL [ .red:has(#descendant:is(.a .b)) ] #parent.classList.add('a') : check #has_scope color assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" -PASS [ .red:has(#descendant:is(.a .b)) ] #parent.classList.remove('a') : check matches (false) -PASS [ .red:has(#descendant:is(.a .b)) ] #parent.classList.remove('a') : check #has_scope color -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.add('a') : check matches (true) -FAIL [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.add('a') : check #has_scope color assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.remove('a') : check matches (false) -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.remove('a') : check #has_scope color -PASS [ .red:has(#descendant:is(.a .b)) ] #child.classList.add('a') : check matches (true) -PASS [ .red:has(#descendant:is(.a .b)) ] #child.classList.add('a') : check #has_scope color -PASS [ .red:has(#descendant:is(.a .b)) ] #child.classList.remove('a') : check matches (false) -PASS [ .red:has(#descendant:is(.a .b)) ] #child.classList.remove('a') : check #has_scope color -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.remove('red') : check matches (false) -PASS [ .red:has(#descendant:is(.a .b)) ] #has_scope.classList.remove('red') : check #has_scope color -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #has_scope.classList.add('green') : check matches (false) -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #has_scope.classList.add('green') : check #has_scope color -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #parent_previous.classList.add('c') : check matches (true) -FAIL [ .green:has(#descendant:is(.c ~ .d .e)) ] #parent_previous.classList.add('c') : check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #parent_previous.classList.remove('c') : check matches (false) -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #parent_previous.classList.remove('c') : check #has_scope color -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #previous.classList.add('c') : check matches (true) -FAIL [ .green:has(#descendant:is(.c ~ .d .e)) ] #previous.classList.add('c') : check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #previous.classList.remove('c') : check matches (false) -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #previous.classList.remove('c') : check #has_scope color -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #child_previous.classList.add('c') : check matches (true) -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #child_previous.classList.add('c') : check #has_scope color -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #child_previous.classList.remove('c') : check matches (false) -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #child_previous.classList.remove('c') : check #has_scope color -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #has_scope.classList.remove('green') : check matches (false) -PASS [ .green:has(#descendant:is(.c ~ .d .e)) ] #has_scope.classList.remove('green') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.add('blue') : check matches (false) -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.add('blue') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #previous.classList.add('f') : check matches (true) -FAIL [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #previous.classList.add('f') : check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #previous.classList.remove('f') : check matches (false) -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #previous.classList.remove('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.add('f') : check matches (true) -FAIL [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.add('f') : check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.remove('f') : check matches (false) -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.remove('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #direct_next.classList.add('f') : check matches (true) -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #direct_next.classList.add('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #direct_next.classList.remove('f') : check matches (false) -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #direct_next.classList.remove('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.remove('blue') : check matches (false) -PASS [ .blue:has(~ #indirect_next:is(.f ~ .g)) ] #has_scope.classList.remove('blue') : check #has_scope color -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #has_scope.classList.add('yellow') : check matches (false) -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #has_scope.classList.add('yellow') : check #has_scope color -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #parent.classList.add('h') : check matches (true) -FAIL [ .yellow:has(~ #indirect_next:is(.h .i)) ] #parent.classList.add('h') : check #has_scope color assert_equals: expected "rgb(255, 255, 0)" but got "rgb(128, 128, 128)" -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #parent.classList.remove('h') : check matches (false) -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #parent.classList.remove('h') : check #has_scope color -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #has_scope.classList.remove('yellow') : check matches (false) -PASS [ .yellow:has(~ #indirect_next:is(.h .i)) ] #has_scope.classList.remove('yellow') : check #has_scope color -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #has_scope.classList.add('purple') : check matches (false) -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #has_scope.classList.add('purple') : check #has_scope color -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #parent_previous.classList.add('j') : check matches (true) -FAIL [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #parent_previous.classList.add('j') : check #has_scope color assert_equals: expected "rgb(128, 0, 128)" but got "rgb(128, 128, 128)" -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #parent_previous.classList.remove('j') : check matches (false) -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #parent_previous.classList.remove('j') : check #has_scope color -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #has_scope.classList.remove('purple') : check matches (false) -PASS [ .purple:has(~ #indirect_next:is(.j ~ .k .l)) ] #has_scope.classList.remove('purple') : check #has_scope color +Found 476 tests; 402 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('red') : check matches (false) +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('red') : check #has_scope color +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.add('a_has_scope') : check matches (true) +FAIL [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.add('a_has_scope') : check #has_scope color assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check matches (false) +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check matches (true) +FAIL [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check #has_scope color assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check matches (false) +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #child.classList.add('a_has_scope') : check matches (true) +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #child.classList.add('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #child.classList.remove('a_has_scope') : check matches (false) +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #child.classList.remove('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.remove('red') : check matches (false) +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.remove('red') : check #has_scope color +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('orangered') : check matches (false) +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('orangered') : check #descendant color +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #parent.classList.add('a_descendant') : check matches (true) +FAIL [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #parent.classList.add('a_descendant') : check #descendant color assert_equals: expected "rgb(255, 69, 0)" but got "rgb(128, 128, 128)" +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check matches (false) +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check matches (true) +FAIL [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check #descendant color assert_equals: expected "rgb(255, 69, 0)" but got "rgb(128, 128, 128)" +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check matches (false) +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #child.classList.add('a_descendant') : check matches (true) +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #child.classList.add('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #child.classList.remove('a_descendant') : check matches (false) +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #child.classList.remove('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.remove('orangered') : check matches (false) +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.remove('orangered') : check #descendant color +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('darkred') : check matches (false) +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('darkred') : check #indirect_next color +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.add('a_indirect_next') : check matches (true) +FAIL [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.add('a_indirect_next') : check #indirect_next color assert_equals: expected "rgb(139, 0, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check matches (false) +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check matches (true) +FAIL [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check #indirect_next color assert_equals: expected "rgb(139, 0, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check matches (false) +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.add('a_indirect_next') : check matches (true) +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.add('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.remove('a_indirect_next') : check matches (false) +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.remove('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('darkred') : check matches (false) +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('darkred') : check #indirect_next color +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('pink') : check matches (false) +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('pink') : check #indirect_next_child color +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('a_indirect_next_child') : check matches (true) +FAIL [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('a_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(255, 192, 203)" but got "rgb(128, 128, 128)" +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check matches (false) +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check matches (true) +FAIL [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(255, 192, 203)" but got "rgb(128, 128, 128)" +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check matches (false) +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.add('a_indirect_next_child') : check matches (true) +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.add('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.remove('a_indirect_next_child') : check matches (false) +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.remove('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('pink') : check matches (false) +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('pink') : check #indirect_next_child color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.add('green') : check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.add('green') : check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.add('c_has_scope') : check matches (true) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.add('c_has_scope') : check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (removal) check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.remove('c_has_scope') : check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.remove('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (insertion) check matches (true) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (insertion) check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (removal) check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #previous.classList.add('c_has_scope') : check matches (true) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #previous.classList.add('c_has_scope') : check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (removal) check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #previous.classList.remove('c_has_scope') : check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #previous.classList.remove('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (insertion) check matches (true) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (insertion) check #has_scope color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(128, 128, 128)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (removal) check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.add('c_has_scope') : check matches (true) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.add('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (insertion) check matches (false) +FAIL [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (removal) check matches (true) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.remove('c_has_scope') : check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.remove('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (insertion) check matches (true) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (removal) check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.remove('green') : check matches (false) +PASS [ .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.remove('green') : check #has_scope color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.add('lightgreen') : check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.add('lightgreen') : check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.add('c_descendant') : check matches (true) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.add('c_descendant') : check #descendant color assert_equals: expected "rgb(144, 238, 144)" but got "rgb(128, 128, 128)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check #descendant color assert_equals: expected "rgb(144, 238, 144)" but got "rgb(128, 128, 128)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.remove('c_descendant') : check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.remove('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (insertion) check matches (true) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (insertion) check #descendant color assert_equals: expected "rgb(144, 238, 144)" but got "rgb(128, 128, 128)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (removal) check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.add('c_descendant') : check matches (true) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.add('c_descendant') : check #descendant color assert_equals: expected "rgb(144, 238, 144)" but got "rgb(128, 128, 128)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (removal) check #descendant color assert_equals: expected "rgb(144, 238, 144)" but got "rgb(128, 128, 128)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.remove('c_descendant') : check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.remove('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (insertion) check matches (true) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (insertion) check #descendant color assert_equals: expected "rgb(144, 238, 144)" but got "rgb(128, 128, 128)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (removal) check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.add('c_descendant') : check matches (true) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.add('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (insertion) check matches (false) +FAIL [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (insertion) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (removal) check matches (true) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.remove('c_descendant') : check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.remove('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (insertion) check matches (true) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (removal) check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.remove('lightgreen') : check matches (false) +PASS [ .lightgreen:has(#descendant:is(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.remove('lightgreen') : check #descendant color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.add('darkgreen') : check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.add('darkgreen') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.add('c_indirect_next') : check matches (true) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.add('c_indirect_next') : check #indirect_next color assert_equals: expected "rgb(0, 100, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next color assert_equals: expected "rgb(0, 100, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.remove('c_indirect_next') : check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.remove('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (insertion) check matches (true) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(0, 100, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (removal) check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.add('c_indirect_next') : check matches (true) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.add('c_indirect_next') : check #indirect_next color assert_equals: expected "rgb(0, 100, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check #indirect_next color assert_equals: expected "rgb(0, 100, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.remove('c_indirect_next') : check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.remove('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (insertion) check matches (true) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(0, 100, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (removal) check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.add('c_indirect_next') : check matches (true) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.add('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (insertion) check matches (false) +FAIL [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (removal) check matches (true) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.remove('c_indirect_next') : check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.remove('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (insertion) check matches (true) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (removal) check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.remove('darkgreen') : check matches (false) +PASS [ .darkgreen:has(#descendant:is(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.remove('darkgreen') : check #indirect_next color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('yellowgreen') : check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('yellowgreen') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('c_indirect_next_child') : check matches (true) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('c_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(128, 128, 128)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(128, 128, 128)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('c_indirect_next_child') : check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (insertion) check matches (true) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(128, 128, 128)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (removal) check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('c_indirect_next_child') : check matches (true) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('c_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(128, 128, 128)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(128, 128, 128)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('c_indirect_next_child') : check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (insertion) check matches (true) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(154, 205, 50)" but got "rgb(128, 128, 128)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (removal) check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.add('c_indirect_next_child') : check matches (true) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.add('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (insertion) check matches (false) +FAIL [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (removal) check matches (true) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.remove('c_indirect_next_child') : check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.remove('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (insertion) check matches (true) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (removal) check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('yellowgreen') : check matches (false) +PASS [ .yellowgreen:has(#descendant:is(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('yellowgreen') : check #indirect_next_child color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('blue') : check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('blue') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #previous.classList.add('f_has_scope') : check matches (true) +FAIL [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #previous.classList.add('f_has_scope') : check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #previous) : (insertion) check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #previous) : (removal) check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #previous.classList.remove('f_has_scope') : check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #previous.classList.remove('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (insertion) check matches (true) +FAIL [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (insertion) check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check matches (true) +FAIL [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #direct_next.classList.add('f_has_scope') : check matches (true) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #direct_next.classList.add('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #direct_next) : (insertion) check matches (false) +FAIL [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #direct_next) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #direct_next) : (removal) check matches (true) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .invalid before #direct_next) : (removal) check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #direct_next.classList.remove('f_has_scope') : check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #direct_next.classList.remove('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (insertion) check matches (true) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (insertion) check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (removal) check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (removal) check #has_scope color +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('blue') : check matches (false) +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('blue') : check #has_scope color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('skyblue') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('skyblue') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.add('f_descendant') : check matches (true) +FAIL [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.add('f_descendant') : check #descendant color assert_equals: expected "rgb(135, 206, 235)" but got "rgb(128, 128, 128)" +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #previous) : (insertion) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #previous) : (removal) check #descendant color assert_equals: expected "rgb(135, 206, 235)" but got "rgb(128, 128, 128)" +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.remove('f_descendant') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.remove('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (insertion) check matches (true) +FAIL [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (insertion) check #descendant color assert_equals: expected "rgb(135, 206, 235)" but got "rgb(128, 128, 128)" +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check matches (true) +FAIL [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check #descendant color assert_equals: expected "rgb(135, 206, 235)" but got "rgb(128, 128, 128)" +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.add('f_descendant') : check matches (true) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.add('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #direct_next) : (insertion) check matches (false) +FAIL [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #direct_next) : (insertion) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(135, 206, 235)" +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #direct_next) : (removal) check matches (true) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .invalid before #direct_next) : (removal) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.remove('f_descendant') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.remove('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (insertion) check matches (true) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (insertion) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (removal) check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (removal) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('skyblue') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('skyblue') : check #descendant color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('lightblue') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('lightblue') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.add('f_indirect_next') : check matches (true) +FAIL [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.add('f_indirect_next') : check #indirect_next color assert_equals: expected "rgb(173, 216, 230)" but got "rgb(128, 128, 128)" +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check #indirect_next color assert_equals: expected "rgb(173, 216, 230)" but got "rgb(128, 128, 128)" +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.remove('f_indirect_next') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.remove('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (insertion) check matches (true) +FAIL [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(173, 216, 230)" but got "rgb(128, 128, 128)" +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check matches (true) +FAIL [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check #indirect_next color assert_equals: expected "rgb(173, 216, 230)" but got "rgb(128, 128, 128)" +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.add('f_indirect_next') : check matches (true) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.add('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (insertion) check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (insertion) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (removal) check matches (true) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (removal) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.remove('f_indirect_next') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.remove('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (insertion) check matches (true) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (insertion) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (removal) check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (removal) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('lightblue') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('lightblue') : check #indirect_next color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('darkblue') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('darkblue') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('f_indirect_next_child') : check matches (true) +FAIL [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('f_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(0, 0, 139)" but got "rgb(128, 128, 128)" +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check matches (true) +FAIL [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(0, 0, 139)" but got "rgb(128, 128, 128)" +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('f_indirect_next_child') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (insertion) check matches (true) +FAIL [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(0, 0, 139)" but got "rgb(128, 128, 128)" +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check matches (true) +FAIL [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(0, 0, 139)" but got "rgb(128, 128, 128)" +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.add('f_indirect_next_child') : check matches (true) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.add('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (insertion) check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (insertion) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (removal) check matches (true) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (removal) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.remove('f_indirect_next_child') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.remove('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (insertion) check matches (true) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (insertion) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (removal) check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (removal) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('darkblue') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('darkblue') : check #indirect_next_child color +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #has_scope.classList.add('yellow') : check matches (false) +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #has_scope.classList.add('yellow') : check #has_scope color +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #parent.classList.add('h_has_scope') : check matches (true) +FAIL [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #parent.classList.add('h_has_scope') : check #has_scope color assert_equals: expected "rgb(255, 255, 0)" but got "rgb(128, 128, 128)" +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #parent.classList.remove('h_has_scope') : check matches (false) +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #parent.classList.remove('h_has_scope') : check #has_scope color +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #has_scope.classList.remove('yellow') : check matches (false) +PASS [ .yellow:has(~ #indirect_next:is(.h_has_scope .i)) ] #has_scope.classList.remove('yellow') : check #has_scope color +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #has_scope.classList.add('ivory') : check matches (false) +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #has_scope.classList.add('ivory') : check #descendant color +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #parent.classList.add('h_descendant') : check matches (true) +FAIL [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #parent.classList.add('h_descendant') : check #descendant color assert_equals: expected "rgb(255, 255, 240)" but got "rgb(128, 128, 128)" +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #parent.classList.remove('h_descendant') : check matches (false) +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #parent.classList.remove('h_descendant') : check #descendant color +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #has_scope.classList.remove('ivory') : check matches (false) +PASS [ .ivory:has(~ #indirect_next:is(.h_descendant .i)) #descendant ] #has_scope.classList.remove('ivory') : check #descendant color +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.add('greenyellow') : check matches (false) +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.add('greenyellow') : check #indirect_next color +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.add('h_indirect_next') : check matches (true) +FAIL [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.add('h_indirect_next') : check #indirect_next color assert_equals: expected "rgb(173, 255, 47)" but got "rgb(128, 128, 128)" +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.remove('h_indirect_next') : check matches (false) +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.remove('h_indirect_next') : check #indirect_next color +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.remove('greenyellow') : check matches (false) +PASS [ .greenyellow:has(~ #indirect_next:is(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.remove('greenyellow') : check #indirect_next color +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('khaki') : check matches (false) +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('khaki') : check #indirect_next_child color +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('h_indirect_next_child') : check matches (true) +FAIL [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('h_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(240, 230, 140)" but got "rgb(128, 128, 128)" +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('h_indirect_next_child') : check matches (false) +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('h_indirect_next_child') : check #indirect_next_child color +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('khaki') : check matches (false) +PASS [ .khaki:has(~ #indirect_next:is(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('khaki') : check #indirect_next_child color +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.add('purple') : check matches (false) +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.add('purple') : check #has_scope color +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.add('j_has_scope') : check matches (true) +FAIL [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.add('j_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 0, 128)" but got "rgb(128, 128, 128)" +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (insertion) check #has_scope color +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (removal) check #has_scope color assert_equals: expected "rgb(128, 0, 128)" but got "rgb(128, 128, 128)" +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.remove('j_has_scope') : check matches (false) +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.remove('j_has_scope') : check #has_scope color +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (insertion) check matches (true) +FAIL [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 0, 128)" but got "rgb(128, 128, 128)" +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (removal) check matches (false) +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (removal) check #has_scope color +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.remove('purple') : check matches (false) +PASS [ .purple:has(~ #indirect_next:is(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.remove('purple') : check #has_scope color +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.add('violet') : check matches (false) +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.add('violet') : check #descendant color +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.add('j_descendant') : check matches (true) +FAIL [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.add('j_descendant') : check #descendant color assert_equals: expected "rgb(238, 130, 238)" but got "rgb(128, 128, 128)" +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check #descendant color +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check #descendant color assert_equals: expected "rgb(238, 130, 238)" but got "rgb(128, 128, 128)" +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.remove('j_descendant') : check matches (false) +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.remove('j_descendant') : check #descendant color +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (insertion) check matches (true) +FAIL [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (insertion) check #descendant color assert_equals: expected "rgb(238, 130, 238)" but got "rgb(128, 128, 128)" +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (removal) check matches (false) +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (removal) check #descendant color +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.remove('violet') : check matches (false) +PASS [ .violet:has(~ #indirect_next:is(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.remove('violet') : check #descendant color +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.add('orchid') : check matches (false) +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.add('orchid') : check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.add('j_indirect_next') : check matches (true) +FAIL [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.add('j_indirect_next') : check #indirect_next color assert_equals: expected "rgb(218, 112, 214)" but got "rgb(128, 128, 128)" +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next color assert_equals: expected "rgb(218, 112, 214)" but got "rgb(128, 128, 128)" +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.remove('j_indirect_next') : check matches (false) +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.remove('j_indirect_next') : check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (insertion) check matches (true) +FAIL [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(218, 112, 214)" but got "rgb(128, 128, 128)" +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (removal) check matches (false) +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (removal) check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.remove('orchid') : check matches (false) +PASS [ .orchid:has(~ #indirect_next:is(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.remove('orchid') : check #indirect_next color +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('plum') : check matches (false) +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('plum') : check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('j_indirect_next_child') : check matches (true) +FAIL [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('j_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(221, 160, 221)" but got "rgb(128, 128, 128)" +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check matches (false) +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check matches (true) +FAIL [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(221, 160, 221)" but got "rgb(128, 128, 128)" +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('j_indirect_next_child') : check matches (false) +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('j_indirect_next_child') : check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (insertion) check matches (true) +FAIL [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(221, 160, 221)" but got "rgb(128, 128, 128)" +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (removal) check matches (false) +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (removal) check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('plum') : check matches (false) +PASS [ .plum:has(~ #indirect_next:is(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('plum') : check #indirect_next_child color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('orange') : check matches (false) PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('orange') : check #has_scope color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #parent.classList.add('m') : check matches (true)
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt index 4a306fc7..a6665c6 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt
@@ -1,69 +1,437 @@ This is a testharness.js-based test. -Found 92 tests; 80 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.add('red') : check matches (true) -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.add('red') : check #has_scope color -PASS [ .red:has(#descendant:not(.a .b)) ] #parent.classList.add('a') : check matches (false) -FAIL [ .red:has(#descendant:not(.a .b)) ] #parent.classList.add('a') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)" -PASS [ .red:has(#descendant:not(.a .b)) ] #parent.classList.remove('a') : check matches (true) -PASS [ .red:has(#descendant:not(.a .b)) ] #parent.classList.remove('a') : check #has_scope color -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.add('a') : check matches (false) -FAIL [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.add('a') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)" -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.remove('a') : check matches (true) -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.remove('a') : check #has_scope color -PASS [ .red:has(#descendant:not(.a .b)) ] #child.classList.add('a') : check matches (false) -PASS [ .red:has(#descendant:not(.a .b)) ] #child.classList.add('a') : check #has_scope color -PASS [ .red:has(#descendant:not(.a .b)) ] #child.classList.remove('a') : check matches (true) -PASS [ .red:has(#descendant:not(.a .b)) ] #child.classList.remove('a') : check #has_scope color -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.remove('red') : check matches (false) -PASS [ .red:has(#descendant:not(.a .b)) ] #has_scope.classList.remove('red') : check #has_scope color -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #has_scope.classList.add('green') : check matches (true) -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #has_scope.classList.add('green') : check #has_scope color -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #parent_previous.classList.add('c') : check matches (false) -FAIL [ .green:has(#descendant:not(.c ~ .d .e)) ] #parent_previous.classList.add('c') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #parent_previous.classList.remove('c') : check matches (true) -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #parent_previous.classList.remove('c') : check #has_scope color -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #previous.classList.add('c') : check matches (false) -FAIL [ .green:has(#descendant:not(.c ~ .d .e)) ] #previous.classList.add('c') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #previous.classList.remove('c') : check matches (true) -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #previous.classList.remove('c') : check #has_scope color -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #child_previous.classList.add('c') : check matches (false) -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #child_previous.classList.add('c') : check #has_scope color -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #child_previous.classList.remove('c') : check matches (true) -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #child_previous.classList.remove('c') : check #has_scope color -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #has_scope.classList.remove('green') : check matches (false) -PASS [ .green:has(#descendant:not(.c ~ .d .e)) ] #has_scope.classList.remove('green') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.add('blue') : check matches (true) -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.add('blue') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #previous.classList.add('f') : check matches (false) -FAIL [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #previous.classList.add('f') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #previous.classList.remove('f') : check matches (true) -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #previous.classList.remove('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.add('f') : check matches (false) -FAIL [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.add('f') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.remove('f') : check matches (true) -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.remove('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #direct_next.classList.add('f') : check matches (false) -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #direct_next.classList.add('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #direct_next.classList.remove('f') : check matches (true) -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #direct_next.classList.remove('f') : check #has_scope color -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.remove('blue') : check matches (false) -PASS [ .blue:has(~ #indirect_next:not(.f ~ .g)) ] #has_scope.classList.remove('blue') : check #has_scope color -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #has_scope.classList.add('yellow') : check matches (true) -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #has_scope.classList.add('yellow') : check #has_scope color -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #parent.classList.add('h') : check matches (false) -FAIL [ .yellow:has(~ #indirect_next:not(.h .i)) ] #parent.classList.add('h') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)" -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #parent.classList.remove('h') : check matches (true) -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #parent.classList.remove('h') : check #has_scope color -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #has_scope.classList.remove('yellow') : check matches (false) -PASS [ .yellow:has(~ #indirect_next:not(.h .i)) ] #has_scope.classList.remove('yellow') : check #has_scope color -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #has_scope.classList.add('purple') : check matches (true) -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #has_scope.classList.add('purple') : check #has_scope color -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #parent_previous.classList.add('j') : check matches (false) -FAIL [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #parent_previous.classList.add('j') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(128, 0, 128)" -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #parent_previous.classList.remove('j') : check matches (true) -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #parent_previous.classList.remove('j') : check #has_scope color -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #has_scope.classList.remove('purple') : check matches (false) -PASS [ .purple:has(~ #indirect_next:not(.j ~ .k .l)) ] #has_scope.classList.remove('purple') : check #has_scope color +Found 460 tests; 394 PASS, 66 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('red') : check matches (true) +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('red') : check #has_scope color +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.add('a_has_scope') : check matches (false) +FAIL [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.add('a_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)" +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check matches (true) +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check matches (false) +FAIL [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)" +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check matches (true) +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #child.classList.add('a_has_scope') : check matches (false) +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #child.classList.add('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #child.classList.remove('a_has_scope') : check matches (true) +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #child.classList.remove('a_has_scope') : check #has_scope color +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.remove('red') : check matches (false) +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.remove('red') : check #has_scope color +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('orangered') : check matches (true) +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('orangered') : check #descendant color +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #parent.classList.add('a_descendant') : check matches (false) +FAIL [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #parent.classList.add('a_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 69, 0)" +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check matches (true) +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check matches (false) +FAIL [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 69, 0)" +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check matches (true) +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #child.classList.add('a_descendant') : check matches (false) +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #child.classList.add('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #child.classList.remove('a_descendant') : check matches (true) +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #child.classList.remove('a_descendant') : check #descendant color +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.remove('orangered') : check matches (false) +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.remove('orangered') : check #descendant color +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('darkred') : check matches (true) +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('darkred') : check #indirect_next color +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.add('a_indirect_next') : check matches (false) +FAIL [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.add('a_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(139, 0, 0)" +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check matches (true) +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check matches (false) +FAIL [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(139, 0, 0)" +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check matches (true) +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.add('a_indirect_next') : check matches (false) +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.add('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.remove('a_indirect_next') : check matches (true) +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.remove('a_indirect_next') : check #indirect_next color +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('darkred') : check matches (false) +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('darkred') : check #indirect_next color +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('pink') : check matches (true) +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('pink') : check #indirect_next_child color +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('a_indirect_next_child') : check matches (false) +FAIL [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('a_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 192, 203)" +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check matches (true) +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check matches (false) +FAIL [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 192, 203)" +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check matches (true) +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.add('a_indirect_next_child') : check matches (false) +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.add('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.remove('a_indirect_next_child') : check matches (true) +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.remove('a_indirect_next_child') : check #indirect_next_child color +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('pink') : check matches (false) +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('pink') : check #indirect_next_child color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.add('green') : check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.add('green') : check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.add('c_has_scope') : check matches (false) +FAIL [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.add('c_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #parent_previous) : (removal) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.remove('c_has_scope') : check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #parent_previous.classList.remove('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (insertion) check matches (false) +FAIL [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (removal) check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #parent_previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #previous.classList.add('c_has_scope') : check matches (false) +FAIL [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #previous.classList.add('c_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (insertion) check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (removal) check matches (false) +FAIL [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #previous) : (removal) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #previous.classList.remove('c_has_scope') : check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #previous.classList.remove('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (insertion) check matches (false) +FAIL [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 128, 0)" +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (removal) check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.add('c_has_scope') : check matches (false) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.add('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (insertion) check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (removal) check matches (false) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .invalid before #child_previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.remove('c_has_scope') : check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #child_previous.classList.remove('c_has_scope') : check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (insertion) check matches (false) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (insertion) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (removal) check matches (true) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] insert/remove .c_has_scope before #child_previous) : (removal) check #has_scope color +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.remove('green') : check matches (false) +PASS [ .green:has(#descendant:not(.p + .c_has_scope ~ .d .e)) ] #has_scope.classList.remove('green') : check #has_scope color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.add('lightgreen') : check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.add('lightgreen') : check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.add('c_descendant') : check matches (false) +FAIL [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.add('c_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.remove('c_descendant') : check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #parent_previous.classList.remove('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (insertion) check matches (false) +FAIL [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (insertion) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (removal) check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #parent_previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.add('c_descendant') : check matches (false) +FAIL [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.add('c_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (insertion) check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (removal) check matches (false) +FAIL [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #previous) : (removal) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.remove('c_descendant') : check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #previous.classList.remove('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (insertion) check matches (false) +FAIL [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (insertion) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(144, 238, 144)" +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (removal) check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.add('c_descendant') : check matches (false) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.add('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (insertion) check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (removal) check matches (false) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .invalid before #child_previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.remove('c_descendant') : check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #child_previous.classList.remove('c_descendant') : check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (insertion) check matches (false) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (insertion) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (removal) check matches (true) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] insert/remove .c_descendant before #child_previous) : (removal) check #descendant color +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.remove('lightgreen') : check matches (false) +PASS [ .lightgreen:has(#descendant:not(.p + .c_descendant ~ .d .e)) #descendant ] #has_scope.classList.remove('lightgreen') : check #descendant color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.add('darkgreen') : check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.add('darkgreen') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.add('c_indirect_next') : check matches (false) +FAIL [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.add('c_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.remove('c_indirect_next') : check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #parent_previous.classList.remove('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (insertion) check matches (false) +FAIL [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (removal) check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #parent_previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.add('c_indirect_next') : check matches (false) +FAIL [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.add('c_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check matches (false) +FAIL [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.remove('c_indirect_next') : check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #previous.classList.remove('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (insertion) check matches (false) +FAIL [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 100, 0)" +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (removal) check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.add('c_indirect_next') : check matches (false) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.add('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (insertion) check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (removal) check matches (false) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .invalid before #child_previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.remove('c_indirect_next') : check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #child_previous.classList.remove('c_indirect_next') : check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (insertion) check matches (false) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (insertion) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (removal) check matches (true) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] insert/remove .c_indirect_next before #child_previous) : (removal) check #indirect_next color +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.remove('darkgreen') : check matches (false) +PASS [ .darkgreen:has(#descendant:not(.p + .c_indirect_next ~ .d .e)) ~ #indirect_next ] #has_scope.classList.remove('darkgreen') : check #indirect_next color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('yellowgreen') : check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('yellowgreen') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('c_indirect_next_child') : check matches (false) +FAIL [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('c_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('c_indirect_next_child') : check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (insertion) check matches (false) +FAIL [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (removal) check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #parent_previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('c_indirect_next_child') : check matches (false) +FAIL [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('c_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check matches (false) +FAIL [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('c_indirect_next_child') : check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (insertion) check matches (false) +FAIL [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(154, 205, 50)" +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (removal) check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.add('c_indirect_next_child') : check matches (false) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.add('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (insertion) check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (removal) check matches (false) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #child_previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.remove('c_indirect_next_child') : check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #child_previous.classList.remove('c_indirect_next_child') : check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (insertion) check matches (false) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (insertion) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (removal) check matches (true) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] insert/remove .c_indirect_next_child before #child_previous) : (removal) check #indirect_next_child color +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('yellowgreen') : check matches (false) +PASS [ .yellowgreen:has(#descendant:not(.p + .c_indirect_next_child ~ .d .e)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('yellowgreen') : check #indirect_next_child color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('blue') : check matches (true) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('blue') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #previous.classList.add('f_has_scope') : check matches (false) +FAIL [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #previous.classList.add('f_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #previous.classList.remove('f_has_scope') : check matches (true) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #previous.classList.remove('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (insertion) check matches (false) +FAIL [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check matches (true) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check matches (false) +FAIL [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check matches (true) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #direct_next.classList.add('f_has_scope') : check matches (false) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #direct_next.classList.add('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #direct_next.classList.remove('f_has_scope') : check matches (true) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #direct_next.classList.remove('f_has_scope') : check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (insertion) check matches (false) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (insertion) check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (removal) check matches (true) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #direct_next) : (removal) check #has_scope color +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('blue') : check matches (false) +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('blue') : check #has_scope color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('skyblue') : check matches (true) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('skyblue') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.add('f_descendant') : check matches (false) +FAIL [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.add('f_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(135, 206, 235)" +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.remove('f_descendant') : check matches (true) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #previous.classList.remove('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (insertion) check matches (false) +FAIL [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (insertion) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(135, 206, 235)" +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check matches (true) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check matches (false) +FAIL [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(135, 206, 235)" +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check matches (true) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.add('f_descendant') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.add('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.remove('f_descendant') : check matches (true) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.remove('f_descendant') : check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (insertion) check matches (false) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (insertion) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (removal) check matches (true) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #direct_next) : (removal) check #descendant color +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('skyblue') : check matches (false) +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('skyblue') : check #descendant color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('lightblue') : check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('lightblue') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.add('f_indirect_next') : check matches (false) +FAIL [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.add('f_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(173, 216, 230)" +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (insertion) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check matches (false) +FAIL [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #previous) : (removal) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(173, 216, 230)" +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.remove('f_indirect_next') : check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #previous.classList.remove('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (insertion) check matches (false) +FAIL [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(173, 216, 230)" +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check matches (false) +FAIL [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(173, 216, 230)" +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.add('f_indirect_next') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.add('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (insertion) check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (insertion) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (removal) check matches (false) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .invalid before #direct_next) : (removal) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.remove('f_indirect_next') : check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.remove('f_indirect_next') : check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (insertion) check matches (false) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (insertion) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (removal) check matches (true) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #direct_next) : (removal) check #indirect_next color +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('lightblue') : check matches (false) +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('lightblue') : check #indirect_next color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('darkblue') : check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('darkblue') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('f_indirect_next_child') : check matches (false) +FAIL [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.add('f_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 139)" +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (insertion) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check matches (false) +FAIL [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 139)" +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('f_indirect_next_child') : check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #previous.classList.remove('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (insertion) check matches (false) +FAIL [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 139)" +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check matches (false) +FAIL [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 139)" +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.add('f_indirect_next_child') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.add('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (insertion) check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (insertion) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (removal) check matches (false) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #direct_next) : (removal) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.remove('f_indirect_next_child') : check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.remove('f_indirect_next_child') : check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (insertion) check matches (false) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (insertion) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (removal) check matches (true) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #direct_next) : (removal) check #indirect_next_child color +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('darkblue') : check matches (false) +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('darkblue') : check #indirect_next_child color +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #has_scope.classList.add('yellow') : check matches (true) +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #has_scope.classList.add('yellow') : check #has_scope color +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #parent.classList.add('h_has_scope') : check matches (false) +FAIL [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #parent.classList.add('h_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 0)" +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #parent.classList.remove('h_has_scope') : check matches (true) +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #parent.classList.remove('h_has_scope') : check #has_scope color +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #has_scope.classList.remove('yellow') : check matches (false) +PASS [ .yellow:has(~ #indirect_next:not(.h_has_scope .i)) ] #has_scope.classList.remove('yellow') : check #has_scope color +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #has_scope.classList.add('ivory') : check matches (true) +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #has_scope.classList.add('ivory') : check #descendant color +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #parent.classList.add('h_descendant') : check matches (false) +FAIL [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #parent.classList.add('h_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 255, 240)" +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #parent.classList.remove('h_descendant') : check matches (true) +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #parent.classList.remove('h_descendant') : check #descendant color +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #has_scope.classList.remove('ivory') : check matches (false) +PASS [ .ivory:has(~ #indirect_next:not(.h_descendant .i)) #descendant ] #has_scope.classList.remove('ivory') : check #descendant color +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.add('greenyellow') : check matches (true) +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.add('greenyellow') : check #indirect_next color +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.add('h_indirect_next') : check matches (false) +FAIL [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.add('h_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(173, 255, 47)" +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.remove('h_indirect_next') : check matches (true) +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #parent.classList.remove('h_indirect_next') : check #indirect_next color +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.remove('greenyellow') : check matches (false) +PASS [ .greenyellow:has(~ #indirect_next:not(.h_indirect_next .i)) ~ #indirect_next ] #has_scope.classList.remove('greenyellow') : check #indirect_next color +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('khaki') : check matches (true) +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('khaki') : check #indirect_next_child color +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('h_indirect_next_child') : check matches (false) +FAIL [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.add('h_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(240, 230, 140)" +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('h_indirect_next_child') : check matches (true) +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('h_indirect_next_child') : check #indirect_next_child color +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('khaki') : check matches (false) +PASS [ .khaki:has(~ #indirect_next:not(.h_indirect_next_child .i)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('khaki') : check #indirect_next_child color +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.add('purple') : check matches (true) +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.add('purple') : check #has_scope color +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.add('j_has_scope') : check matches (false) +FAIL [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.add('j_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(128, 0, 128)" +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (insertion) check #has_scope color +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .invalid before #parent_previous) : (removal) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(128, 0, 128)" +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.remove('j_has_scope') : check matches (true) +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #parent_previous.classList.remove('j_has_scope') : check #has_scope color +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (insertion) check matches (false) +FAIL [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (insertion) check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(128, 0, 128)" +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (removal) check matches (true) +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] insert/remove .j_has_scope before #parent_previous) : (removal) check #has_scope color +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.remove('purple') : check matches (false) +PASS [ .purple:has(~ #indirect_next:not(.p + .j_has_scope ~ .k .l)) ] #has_scope.classList.remove('purple') : check #has_scope color +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.add('violet') : check matches (true) +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.add('violet') : check #descendant color +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.add('j_descendant') : check matches (false) +FAIL [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.add('j_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(238, 130, 238)" +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (insertion) check #descendant color +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .invalid before #parent_previous) : (removal) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(238, 130, 238)" +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.remove('j_descendant') : check matches (true) +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #parent_previous.classList.remove('j_descendant') : check #descendant color +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (insertion) check matches (false) +FAIL [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (insertion) check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(238, 130, 238)" +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (removal) check matches (true) +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] insert/remove .j_descendant before #parent_previous) : (removal) check #descendant color +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.remove('violet') : check matches (false) +PASS [ .violet:has(~ #indirect_next:not(.p + .j_descendant ~ .k .l)) #descendant ] #has_scope.classList.remove('violet') : check #descendant color +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.add('orchid') : check matches (true) +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.add('orchid') : check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.add('j_indirect_next') : check matches (false) +FAIL [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.add('j_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(218, 112, 214)" +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(218, 112, 214)" +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.remove('j_indirect_next') : check matches (true) +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #parent_previous.classList.remove('j_indirect_next') : check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (insertion) check matches (false) +FAIL [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (insertion) check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(218, 112, 214)" +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (removal) check matches (true) +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] insert/remove .j_indirect_next before #parent_previous) : (removal) check #indirect_next color +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.remove('orchid') : check matches (false) +PASS [ .orchid:has(~ #indirect_next:not(.p + .j_indirect_next ~ .k .l)) ~ #indirect_next ] #has_scope.classList.remove('orchid') : check #indirect_next color +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('plum') : check matches (true) +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('plum') : check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('j_indirect_next_child') : check matches (false) +FAIL [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.add('j_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(221, 160, 221)" +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check matches (true) +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (insertion) check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check matches (false) +FAIL [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .invalid before #parent_previous) : (removal) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(221, 160, 221)" +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('j_indirect_next_child') : check matches (true) +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #parent_previous.classList.remove('j_indirect_next_child') : check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (insertion) check matches (false) +FAIL [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (insertion) check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(221, 160, 221)" +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (removal) check matches (true) +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] insert/remove .j_indirect_next_child before #parent_previous) : (removal) check #indirect_next_child color +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('plum') : check matches (false) +PASS [ .plum:has(~ #indirect_next:not(.p + .j_indirect_next_child ~ .k .l)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('plum') : check #indirect_next_child color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('orange') : check matches (true) PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('orange') : check #has_scope color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #parent.classList.add('m') : check matches (false)
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/parsing/parse-has-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/parsing/parse-has-expected.txt index bd13fe7..49325f3 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/parsing/parse-has-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/parsing/parse-has-expected.txt
@@ -24,7 +24,7 @@ PASS ".a:has(.b):has(.c)" should be a valid selector PASS "*|*:has(*)" should be a valid selector PASS ":has(*|*)" should be a valid selector -FAIL ".a:has()" should be an invalid selector assert_throws_dom: ".a:has()" should throw in querySelector function "() => document.querySelector(selector)" did not throw +PASS ".a:has()" should be a valid selector PASS ":has" should be an invalid selector PASS ".a:has" should be an invalid selector PASS ".a:has b" should be an invalid selector
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/devtools/extensions/extensions-api-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/devtools/extensions/extensions-api-expected.txt index df21faa..dd7e0712 100644 --- a/third_party/blink/web_tests/platform/generic/http/tests/devtools/extensions/extensions-api-expected.txt +++ b/third_party/blink/web_tests/platform/generic/http/tests/devtools/extensions/extensions-api-expected.txt
@@ -65,6 +65,10 @@ } themeName : "themeNameForTest" } + recorder : { + registerRecorderExtensionPlugin : <function> + unregisterRecorderExtensionPlugin : <function> + } resources : { addRequestHeaders : <function> getHAR : <function>
diff --git a/third_party/blink/web_tests/platform/generic/virtual/system-color-compute/external/wpt/css/css-color/system-color-compute-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/system-color-compute/external/wpt/css/css-color/system-color-compute-expected.txt new file mode 100644 index 0000000..d16956e --- /dev/null +++ b/third_party/blink/web_tests/platform/generic/virtual/system-color-compute/external/wpt/css/css-color/system-color-compute-expected.txt
@@ -0,0 +1,30 @@ +This is a testharness.js-based test. +PASS color-scheme property affects Menu system color keyword +FAIL System color doesn't compute to itself on color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on color assert_false: expected false got true +FAIL System color doesn't compute to itself on background-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on background-color assert_false: expected false got true +FAIL System color doesn't compute to itself on box-shadow assert_not_equals: got disallowed value "rgb(18, 18, 18) 2px 2px 0px 0px" +FAIL Inherited system color keyword is observable on box-shadow assert_false: expected false got true +FAIL System color doesn't compute to itself on text-shadow assert_not_equals: got disallowed value "menu 2px 2px 0px" +FAIL Inherited system color keyword is observable on text-shadow assert_false: expected false got true +FAIL System color doesn't compute to itself on border-left-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-left-color assert_false: expected false got true +FAIL System color doesn't compute to itself on border-top-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-top-color assert_false: expected false got true +FAIL System color doesn't compute to itself on border-right-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-right-color assert_false: expected false got true +FAIL System color doesn't compute to itself on border-bottom-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on border-bottom-color assert_false: expected false got true +FAIL System color doesn't compute to itself on column-rule-color assert_not_equals: got disallowed value "menu" +FAIL Inherited system color keyword is observable on column-rule-color assert_false: expected false got true +FAIL System color doesn't compute to itself on outline-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on outline-color assert_false: expected false got true +FAIL System color doesn't compute to itself on caret-color assert_not_equals: got disallowed value "rgb(18, 18, 18)" +FAIL Inherited system color keyword is observable on caret-color assert_false: expected false got true +FAIL System color doesn't compute to itself on fill assert_not_equals: got disallowed value "menu" +FAIL Inherited system color keyword is observable on fill assert_false: expected false got true +FAIL System color doesn't compute to itself on stroke assert_not_equals: got disallowed value "menu" +FAIL Inherited system color keyword is observable on stroke assert_false: expected false got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt new file mode 100644 index 0000000..ed296ab9 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +PASS Redirects done from within a service-worker should not be exposed to client ResourceTiming +PASS Connection info from within a service-worker should not be exposed to client ResourceTiming +PASS requestStart should never be before fetchStart +PASS Delay from within service-worker (after internal fetching) should be accessible through `responseStart` +PASS Delay from within service-worker (before internal fetching) should be measured before responseStart in the client ResourceTiming entry +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js b/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js deleted file mode 100644 index 02bd7ec..0000000 --- a/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js +++ /dev/null
@@ -1,72 +0,0 @@ -/** - * This file co-works with a html file and utils.js to test a promise that - * should be deferred during prerendering. - * - * Usage example: - * Suppose the html is "prerender-promise-test.html" - * On prerendering page, prerender-promise-test.html?prerendering: - * const prerenderEventCollector = new PrerenderEventCollector(); - * const promise = {a promise that should be deferred during prerendering}; - * prerenderEventCollector.start(promise, {promise name}); - * - * On the initiator page, prerender-promise-test.html: - * execute - * `loadInitiatorPage();` - */ - -// Collects events that happen relevant to a prerendering page. -// An event is added when: -// 1. start() is called. -// 2. a prerenderingchange event is dispatched on this document. -// 3. the promise passed to start() is resolved. -// 4. addEvent() is called manually. -class PrerenderEventCollector { - constructor() { - this.eventsSeen_ = []; - } - - // Adds an event to `eventsSeen_` along with the prerendering state of the - // page. - addEvent(eventMessage) { - this.eventsSeen_.push( - {event: eventMessage, prerendering: document.prerendering}); - } - - // Starts collecting events until the promise resolves. Triggers activation by - // telling the initiator page that it is ready for activation. - async start(promise, promiseName) { - assert_true(document.prerendering); - this.addEvent(`started waiting ${promiseName}`); - promise - .then( - () => { - this.addEvent(`finished waiting ${promiseName}`); - }, - (error) => { - if (error instanceof Error) - error = error.name; - this.addEvent(`${promiseName} rejected: ${error}`); - }) - .finally(() => { - // Used to communicate with the main test page. - const testChannel = new BroadcastChannel('test-channel'); - // Send the observed events back to the main test page. - testChannel.postMessage(this.eventsSeen_); - testChannel.close(); - window.close(); - }); - document.addEventListener('prerenderingchange', () => { - this.addEvent('prerendering change'); - }); - - // Post a task to give the implementation a chance to fail in case it - // resolves a promise without waiting for activation. - setTimeout(() => { - // Used to communicate with the initiator page. - const prerenderChannel = new BroadcastChannel('prerender-channel'); - // Inform the initiator page that this page is ready to be activated. - prerenderChannel.postMessage('readyToActivate'); - prerenderChannel.close(); - }, 0); - } -}
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/web-auth.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/web-auth.https.html index ced37c2..06cf935 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/resources/web-auth.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/web-auth.https.html
@@ -1,8 +1,8 @@ <!DOCTYPE html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="utils.js"></script> -<script src="deferred-promise-utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/deferred-promise-utils.js"></script> <script type="module"> // Access external/wpt/credential-management/support/otpcredential-helper.js in
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-web-auth.https.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-web-auth.https.html index 190e2072..20a31d0 100644 --- a/third_party/blink/web_tests/wpt_internal/prerender/restriction-web-auth.https.html +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-web-auth.https.html
@@ -3,12 +3,15 @@ <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="resources/utils.js"></script> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> <body> <script> promise_test(async t => { - const bc = new BroadcastChannel('test-channel'); + const uid = token(); + const bc = new PrerenderChannel('test-channel', uid); + t.add_cleanup(_ => bc.close()); const gotMessage = new Promise(resolve => { @@ -18,7 +21,7 @@ once: true }); }); - const url = `resources/web-auth.https.html`; + const url = `resources/web-auth.https.html?uid=${uid}`; window.open(url, '_blank', 'noopener'); const result = await gotMessage; @@ -34,6 +37,8 @@ assert_equals(result[i].prerendering, expected[i].prerendering, `prerendering[${i}]`); } + // Send a close signal to PrerenderEventCollector on the prerendered page. + new PrerenderChannel('close', uid).postMessage(''); }, `The access to the Web Authentication API should be deferred until the prerendered page is activated`);
diff --git a/third_party/closure_compiler/externs/terminal_private.js b/third_party/closure_compiler/externs/terminal_private.js index ba1c367e..aa89101 100644 --- a/third_party/closure_compiler/externs/terminal_private.js +++ b/third_party/closure_compiler/externs/terminal_private.js
@@ -111,6 +111,7 @@ * Returns an object containing info about ChromeOS settings that affect the * Terminal, e.g. which feature flags are enabled. * @param {function({ + * multi_profile: boolean, * tmux_integration: boolean * }): void} callback Callback that will be called with the info object. */
diff --git a/third_party/grpc/BUILD.gn b/third_party/grpc/BUILD.gn index 74404b6..8d33f84 100644 --- a/third_party/grpc/BUILD.gn +++ b/third_party/grpc/BUILD.gn
@@ -2051,7 +2051,85 @@ sources = [ "src/third_party/cares/ares_build.h" ] if (enable_grpc_ares) { - sources += [] + sources += [ + "//third_party/cares/ares.h", + "//third_party/cares/ares__close_sockets.c", + "//third_party/cares/ares__get_hostent.c", + "//third_party/cares/ares__read_line.c", + "//third_party/cares/ares__timeval.c", + "//third_party/cares/ares_android.c", + "//third_party/cares/ares_android.h", + "//third_party/cares/ares_cancel.c", + "//third_party/cares/ares_create_query.c", + "//third_party/cares/ares_data.c", + "//third_party/cares/ares_data.h", + "//third_party/cares/ares_destroy.c", + "//third_party/cares/ares_dns.h", + "//third_party/cares/ares_expand_name.c", + "//third_party/cares/ares_expand_string.c", + "//third_party/cares/ares_fds.c", + "//third_party/cares/ares_free_hostent.c", + "//third_party/cares/ares_free_string.c", + "//third_party/cares/ares_getenv.c", + "//third_party/cares/ares_getenv.h", + "//third_party/cares/ares_gethostbyaddr.c", + "//third_party/cares/ares_gethostbyname.c", + "//third_party/cares/ares_getnameinfo.c", + "//third_party/cares/ares_getopt.c", + "//third_party/cares/ares_getopt.h", + "//third_party/cares/ares_getsock.c", + "//third_party/cares/ares_inet_net_pton.h", + "//third_party/cares/ares_init.c", + "//third_party/cares/ares_iphlpapi.h", + "//third_party/cares/ares_ipv6.h", + "//third_party/cares/ares_library_init.c", + "//third_party/cares/ares_library_init.h", + "//third_party/cares/ares_llist.c", + "//third_party/cares/ares_llist.h", + "//third_party/cares/ares_mkquery.c", + "//third_party/cares/ares_nowarn.c", + "//third_party/cares/ares_nowarn.h", + "//third_party/cares/ares_options.c", + "//third_party/cares/ares_parse_a_reply.c", + "//third_party/cares/ares_parse_aaaa_reply.c", + "//third_party/cares/ares_parse_mx_reply.c", + "//third_party/cares/ares_parse_naptr_reply.c", + "//third_party/cares/ares_parse_ns_reply.c", + "//third_party/cares/ares_parse_ptr_reply.c", + "//third_party/cares/ares_parse_soa_reply.c", + "//third_party/cares/ares_parse_srv_reply.c", + "//third_party/cares/ares_parse_txt_reply.c", + "//third_party/cares/ares_platform.c", + "//third_party/cares/ares_platform.h", + "//third_party/cares/ares_private.h", + "//third_party/cares/ares_process.c", + "//third_party/cares/ares_query.c", + "//third_party/cares/ares_rules.h", + "//third_party/cares/ares_search.c", + "//third_party/cares/ares_send.c", + "//third_party/cares/ares_setup.h", + "//third_party/cares/ares_strcasecmp.c", + "//third_party/cares/ares_strcasecmp.h", + "//third_party/cares/ares_strdup.c", + "//third_party/cares/ares_strdup.h", + "//third_party/cares/ares_strerror.c", + "//third_party/cares/ares_strsplit.c", + "//third_party/cares/ares_strsplit.h", + "//third_party/cares/ares_timeout.c", + "//third_party/cares/ares_version.c", + "//third_party/cares/ares_version.h", + "//third_party/cares/ares_writev.c", + "//third_party/cares/ares_writev.h", + "//third_party/cares/bitncmp.c", + "//third_party/cares/bitncmp.h", + "//third_party/cares/config-dos.h", + "//third_party/cares/config-win32.h", + "//third_party/cares/inet_net_pton.c", + "//third_party/cares/inet_ntop.c", + "//third_party/cares/nameser.h", + "//third_party/cares/setup_once.h", + "//third_party/cares/windows_port.c", + ] } if (is_android) {
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium index b7a6c8d..fee2be39 100644 --- a/third_party/harfbuzz-ng/README.chromium +++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,10 +1,10 @@ Name: harfbuzz-ng Short Name: harfbuzz-ng URL: http://harfbuzz.org -Version: 4.2.1-124 -CPEPrefix: cpe:/a:harfbuzz_project:harfbuzz:4.2.1 -Date: 20220516 -Revision: acdab17ed3507bc9524cb57bef703a983e1031cf +Version: 4.3.0-32 +CPEPrefix: cpe:/a:harfbuzz_project:harfbuzz:4.3.0 +Date: 20220529 +Revision: d61b2074915cf5f8044dcb8e3dafc04b5b58c6b8 Security Critical: yes License: MIT License File: src/COPYING
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 6ba15265..696805f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -54729,6 +54729,7 @@ <int value="-2030255112" label="Bruschetta:disabled"/> <int value="-2030217301" label="password-export:disabled"/> <int value="-2029912304" label="StaleWhileRevalidate2:enabled"/> + <int value="-2028961033" label="SanitizerAPIv0:disabled"/> <int value="-2028402892" label="EnableIkev2Vpn:enabled"/> <int value="-2028336995" label="VirtualKeyboardDarkMode:disabled"/> <int value="-2028232016" label="spurious-power-button-lid-angle-change"/> @@ -57792,6 +57793,7 @@ <int value="-32712825" label="CrOSEnforceSystemAec:disabled"/> <int value="-32385086" label="NtpRecipeTasksModule:disabled"/> <int value="-31444029" label="MediaInspectorLogging:disabled"/> + <int value="-31053177" label="TerminalMultiProfile:enabled"/> <int value="-30966385" label="enable-hardware-overlays"/> <int value="-30208692" label="webview-enable-modern-cookie-same-site"/> <int value="-29877377" label="TabHoverCardImages:disabled"/> @@ -57979,6 +57981,7 @@ label="ChromeHomePersonalizedOmniboxSuggestions:enabled"/> <int value="84911198" label="ScanCardsInWebPayments:disabled"/> <int value="86233339" label="MessagesForAndroidOfferNotification:disabled"/> + <int value="86900696" label="SanitizerAPIv0:enabled"/> <int value="87306743" label="VariationsFakeCrashAfterStartup:disabled"/> <int value="88249612" label="CalendarView:enabled"/> <int value="88437020" label="FeaturePolicy:enabled"/> @@ -58810,6 +58813,7 @@ <int value="643725031" label="disable-touch-feedback"/> <int value="644084236" label="CloseButtonsInactiveTabs:enabled"/> <int value="644189071" label="PermissionsBlacklist:enabled"/> + <int value="644526367" label="TerminalMultiProfile:disabled"/> <int value="646252875" label="ReadItLaterInMenu:enabled"/> <int value="646269021" label="UnifiedSidePanel:disabled"/> <int value="646738320" label="disable-gesture-editing"/> @@ -78559,6 +78563,10 @@ label="The flow got aborted after sign-in (not in enterprise welcome)."/> <int value="12" label="The flow got aborted after sign-in (in enterprise welcome)."/> + <int value="13" + label="The flow was skipped because the profile is already syncing."/> + <int value="14" + label="The flow was skipped due to the value of some policy(ies)."/> </enum> <enum name="ProfileSignInStatus">
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index 4899d02..0015e0a79d 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -61,6 +61,17 @@ </summary> </histogram> +<histogram name="HttpCache.CreateDiskEntry" units="ms" + expires_after="2022-11-25"> + <owner>yhirano@chromium.org</owner> + <owner>net-dev@chromium.org</owner> + <summary> + The time taken to create a disk cache entry. Recorded when the entry is + created for the first time in the HttpCacheTransaction. Not recorded if the + cache is memory-backed. + </summary> +</histogram> + <histogram name="HttpCache.MaxFileSizeOnInit" units="KB" expires_after="2022-02-20"> <owner>shivanisha@chromium.org</owner> @@ -71,6 +82,16 @@ </summary> </histogram> +<histogram name="HttpCache.OpenDiskEntry" units="ms" expires_after="2022-11-25"> + <owner>yhirano@chromium.org</owner> + <owner>net-dev@chromium.org</owner> + <summary> + The time taken to open a disk cache entry. Recorded when the entry is + created for the first time in the HttpCacheTransaction. Not recorded if the + cache is memory-backed. + </summary> +</histogram> + <histogram name="HttpCache.Pattern" enum="HttpCachePattern" expires_after="2022-10-30"> <owner>morlovich@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index ab60b6b..b6dfc2528 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -250,7 +250,7 @@ </histogram> <histogram name="PasswordGeneration.SubmissionAvailableEvent" - enum="PasswordSubmissionEvent" expires_after="M105"> + enum="PasswordSubmissionEvent" expires_after="M111"> <owner>kazinova@google.com</owner> <owner>kolos@chromium.org</owner> <summary> @@ -272,7 +272,7 @@ </histogram> <histogram name="PasswordGeneration.UploadStarted" enum="Boolean" - expires_after="M105"> + expires_after="M111"> <owner>kazinova@google.com</owner> <owner>kolos@chromium.org</owner> <owner>vasilii@chromium.org</owner> @@ -1312,7 +1312,7 @@ </histogram> <histogram name="PasswordManager.CredentialsWithMismatchedDuplicates2" - units="units" expires_after="2022-06-30"> + units="units" expires_after="M111"> <owner>kazinova@google.com</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -1415,7 +1415,7 @@ </histogram> <histogram name="PasswordManager.FilledCredentialWasFromAndroidApp" - enum="PasswordManagerFilledAndroidCredentials" expires_after="M105"> + enum="PasswordManagerFilledAndroidCredentials" expires_after="M111"> <owner>kazinova@google.com</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -1496,7 +1496,7 @@ </histogram> <histogram name="PasswordManager.FormDataDeserializationStatus" - enum="FormDataDeserializationStatus" expires_after="M105"> + enum="FormDataDeserializationStatus" expires_after="M111"> <owner>kazinova@google.com</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -2549,7 +2549,7 @@ </histogram> <histogram name="PasswordManager.ReauthToAccessPasswordInSettings" - enum="PasswordManager.ReauthResult" expires_after="M105"> + enum="PasswordManager.ReauthResult" expires_after="M111"> <owner>kazinova@google.com</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -2760,7 +2760,7 @@ </histogram> <histogram name="PasswordManager.SubmittedFormType" enum="PasswordFormType" - expires_after="M105"> + expires_after="M111"> <owner>kazinova@google.com</owner> <owner>kolos@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml index 4839a287..ed82689 100644 --- a/tools/metrics/histograms/metadata/profile/histograms.xml +++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -336,7 +336,7 @@ </histogram> <histogram name="Profile.Menu.ClickedActionableItem" - enum="ProfileMenuActionableItem" expires_after="2022-06-30"> + enum="ProfileMenuActionableItem" expires_after="2023-06-30"> <owner>droger@chromium.org</owner> <owner>msarda@chromium.org</owner> <owner>chrome-signin-team@google.com</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 50365b1..c34933a 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "b63f94357b0f34298abd3a9b83112bde117301d9", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6214d0c954d720a3c87cf7673903d679d2ae7413/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/23339a6fac0aeb6c2289af885ee4d1df0a9aaf90/trace_processor_shell.exe" }, "linux_arm": { "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893", @@ -14,7 +14,7 @@ }, "mac": { "hash": "264c11ffef682d8a1f737bec52098694092919a4", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/6214d0c954d720a3c87cf7673903d679d2ae7413/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/23339a6fac0aeb6c2289af885ee4d1df0a9aaf90/trace_processor_shell" }, "mac_arm64": { "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc index 8f0b129..7e78968 100644 --- a/ui/message_center/views/message_view.cc +++ b/ui/message_center/views/message_view.cc
@@ -361,7 +361,7 @@ (parent_message_view_ && !parent_message_view_->IsExpanded()) ? parent_message_view_->layer() : layer(); - bool is_nested = (parent_message_view_ && !IsExpanded()) + bool is_nested = (parent_message_view_ && !parent_message_view_->IsExpanded()) ? parent_message_view_->is_nested() : is_nested_; return is_nested ? nested_layer : GetWidget()->GetLayer();
diff --git a/ui/message_center/views/notification_header_view.cc b/ui/message_center/views/notification_header_view.cc index 49ebe63..40de6f8 100644 --- a/ui/message_center/views/notification_header_view.cc +++ b/ui/message_center/views/notification_header_view.cc
@@ -380,6 +380,11 @@ app_icon_view_->SetVisible(visible); } +void NotificationHeaderView::SetTimestampVisible(bool visible) { + timestamp_divider_->SetVisible(visible); + timestamp_view_->SetVisible(visible); +} + void NotificationHeaderView::SetIsInAshNotificationView( bool is_in_ash_notification) { is_in_ash_notification_ = is_in_ash_notification;
diff --git a/ui/message_center/views/notification_header_view.h b/ui/message_center/views/notification_header_view.h index 7f4dbab5..cb413a96 100644 --- a/ui/message_center/views/notification_header_view.h +++ b/ui/message_center/views/notification_header_view.h
@@ -74,6 +74,9 @@ // Shows or hides the app icon. void SetAppIconVisible(bool visible); + // Shows or hides the timestamp and timestamp divider + void SetTimestampVisible(bool visible); + void SetIsInAshNotificationView(bool is_in_ash_notification); // views::View: